[Bf-blender-cvs] [35ecfefaec2] master: Made pose push/relax to breakdown behave smooth on rotations

Sebastian Parborg noreply at git.blender.org
Thu Apr 23 14:15:37 CEST 2020


Commit: 35ecfefaec231772d3cd366d21240636b9940be1
Author: Sebastian Parborg
Date:   Thu Apr 23 14:11:15 2020 +0200
Branches: master
https://developer.blender.org/rB35ecfefaec231772d3cd366d21240636b9940be1

Made pose push/relax to breakdown behave smooth on rotations

A follow up to T67212. I missed that the rotation interpolation had its
own code path.

The previous rotation push code was actually wrong (but smooth).

Now all of the actions behave correctly and is smoothly interpolated.

===================================================================

M	source/blender/editors/armature/pose_slide.c

===================================================================

diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index ae08aee3c47..481282d6df3 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -544,71 +544,56 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
 
   /* only if all channels exist, proceed */
   if (fcu_w && fcu_x && fcu_y && fcu_z) {
-    float quat_prev[4], quat_prev_orig[4];
-    float quat_next[4], quat_next_orig[4];
-    float quat_curr[4], quat_curr_orig[4];
     float quat_final[4];
 
-    copy_qt_qt(quat_curr_orig, pchan->quat);
-
-    /* get 2 quats */
-    quat_prev_orig[0] = evaluate_fcurve(fcu_w, prevFrameF);
-    quat_prev_orig[1] = evaluate_fcurve(fcu_x, prevFrameF);
-    quat_prev_orig[2] = evaluate_fcurve(fcu_y, prevFrameF);
-    quat_prev_orig[3] = evaluate_fcurve(fcu_z, prevFrameF);
-
-    quat_next_orig[0] = evaluate_fcurve(fcu_w, nextFrameF);
-    quat_next_orig[1] = evaluate_fcurve(fcu_x, nextFrameF);
-    quat_next_orig[2] = evaluate_fcurve(fcu_y, nextFrameF);
-    quat_next_orig[3] = evaluate_fcurve(fcu_z, nextFrameF);
-
-    normalize_qt_qt(quat_prev, quat_prev_orig);
-    normalize_qt_qt(quat_next, quat_next_orig);
-    normalize_qt_qt(quat_curr, quat_curr_orig);
-
     /* perform blending */
     if (pso->mode == POSESLIDE_BREAKDOWN) {
       /* Just perform the interpolation between quat_prev and
        * quat_next using pso->percentage as a guide. */
-      interp_qt_qtqt(quat_final, quat_prev, quat_next, pso->percentage);
-    }
-    else if (pso->mode == POSESLIDE_PUSH) {
-      float quat_diff[4];
+      float quat_prev[4];
+      float quat_next[4];
+
+      quat_prev[0] = evaluate_fcurve(fcu_w, prevFrameF);
+      quat_prev[1] = evaluate_fcurve(fcu_x, prevFrameF);
+      quat_prev[2] = evaluate_fcurve(fcu_y, prevFrameF);
+      quat_prev[3] = evaluate_fcurve(fcu_z, prevFrameF);
 
-      /* calculate the delta transform from the previous to the current */
-      /* TODO: investigate ways to favor one transform more? */
-      sub_qt_qtqt(quat_diff, quat_curr, quat_prev);
+      quat_next[0] = evaluate_fcurve(fcu_w, nextFrameF);
+      quat_next[1] = evaluate_fcurve(fcu_x, nextFrameF);
+      quat_next[2] = evaluate_fcurve(fcu_y, nextFrameF);
+      quat_next[3] = evaluate_fcurve(fcu_z, nextFrameF);
 
-      /* increase the original by the delta transform, by an amount determined by percentage */
-      add_qt_qtqt(quat_final, quat_curr, quat_diff, pso->percentage);
+      normalize_qt(quat_prev);
+      normalize_qt(quat_next);
 
-      normalize_qt(quat_final);
+      interp_qt_qtqt(quat_final, quat_prev, quat_next, pso->percentage);
     }
     else {
-      BLI_assert(pso->mode == POSESLIDE_RELAX);
-      float quat_interp[4], quat_final_prev[4];
-      /* TODO: maybe a sensitivity ctrl on top of this is needed */
-      int iters = (int)ceil(10.0f * pso->percentage);
+      /* POSESLIDE_PUSH and POSESLIDE_RELAX. */
+      float quat_breakdown[4];
+      float quat_curr[4];
 
-      copy_qt_qt(quat_final, quat_curr);
+      copy_qt_qt(quat_curr, pchan->quat);
 
-      /* perform this blending several times until a satisfactory result is reached */
-      while (iters-- > 0) {
-        /* calculate the interpolation between the endpoints */
-        interp_qt_qtqt(quat_interp,
-                       quat_prev,
-                       quat_next,
-                       (cframe - pso->prevFrame) / (pso->nextFrame - pso->prevFrame));
+      quat_breakdown[0] = evaluate_fcurve(fcu_w, cframe);
+      quat_breakdown[1] = evaluate_fcurve(fcu_x, cframe);
+      quat_breakdown[2] = evaluate_fcurve(fcu_y, cframe);
+      quat_breakdown[3] = evaluate_fcurve(fcu_z, cframe);
 
-        normalize_qt_qt(quat_final_prev, quat_final);
+      normalize_qt(quat_breakdown);
+      normalize_qt(quat_curr);
 
-        /* tricky interpolations - blending between original and new */
-        interp_qt_qtqt(quat_final, quat_final_prev, quat_interp, 1.0f / 6.0f);
+      if (pso->mode == POSESLIDE_PUSH) {
+        interp_qt_qtqt(quat_final, quat_breakdown, quat_curr, 1.0f + pso->percentage);
+      }
+      else {
+        BLI_assert(pso->mode == POSESLIDE_RELAX);
+        interp_qt_qtqt(quat_final, quat_curr, quat_breakdown, pso->percentage);
       }
     }
 
     /* Apply final to the pose bone, keeping compatible for similar keyframe positions. */
-    quat_to_compatible_quat(pchan->quat, quat_final, quat_curr_orig);
+    quat_to_compatible_quat(pchan->quat, quat_final, pchan->quat);
   }
 
   /* free the path now */



More information about the Bf-blender-cvs mailing list