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:
authorJoshua Leung <aligorith@gmail.com>2009-09-20 16:54:30 +0400
committerJoshua Leung <aligorith@gmail.com>2009-09-20 16:54:30 +0400
commit2f71b49484ee2c45d77784d07a21031d07f699ed (patch)
treea04a1a33972ee7b6078f7a393a781c5813033cb9 /source/blender/editors/armature
parentad25fc829e736be4bbf2e2a125347eda294fdac9 (diff)
2.5 - Yet another round of bugfixes
* Copy Rotation constraint "should" work ok for custom rotation orders now. It now converts both rotations to the form used by the owner. So far, this doesn't seem to have broken any of the test rigs in my test-suite, though new specimens for the hall of flakiness are always welcome. * Fixed many RNA wrapping bugs for Armature data. - Fixed a few wrong tooltips - Made proper refreshes for restpose/posed, etc. * Started converting special quaternion interpolation for Pose Sliding tools (push/relax/breakdown), though this doesn't seem to be working correctly yet. -->> Help to get these working right is welcome :)
Diffstat (limited to 'source/blender/editors/armature')
-rw-r--r--source/blender/editors/armature/poseSlide.c100
1 files changed, 76 insertions, 24 deletions
diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c
index 02c23f01f1e..353503967ec 100644
--- a/source/blender/editors/armature/poseSlide.c
+++ b/source/blender/editors/armature/poseSlide.c
@@ -410,30 +410,82 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo
/* helper for apply() - perform sliding for quaternion rotations (using quat blending) */
static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
{
- // TODO: this is quite evil stuff...
-#if 0 // XXX port...
- /* get 2 quats */
- quat_prev[0] = eval_icu(icu_w, frame_prev);
- quat_prev[1] = eval_icu(icu_x, frame_prev);
- quat_prev[2] = eval_icu(icu_y, frame_prev);
- quat_prev[3] = eval_icu(icu_z, frame_prev);
-
- quat_next[0] = eval_icu(icu_w, frame_next);
- quat_next[1] = eval_icu(icu_x, frame_next);
- quat_next[2] = eval_icu(icu_y, frame_next);
- quat_next[3] = eval_icu(icu_z, frame_next);
-
-#if 0
- /* apply the setting, completely smooth */
- QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
-#else
- /* tricky interpolation */
- QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
- QUATCOPY(quat_orig, pchan->quat);
- QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
- /* done */
-#endif
-#endif
+ FCurve *fcu_w=NULL, *fcu_x=NULL, *fcu_y=NULL, *fcu_z=NULL;
+ bPoseChannel *pchan= pfl->pchan;
+ LinkData *ld=NULL;
+ char *path=NULL;
+ float cframe;
+
+ /* get the path to use - this should be quaternion rotations only (needs care) */
+ path= BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation");
+
+ /* get the current frame number */
+ cframe= (float)pso->cframe;
+
+ /* using this path, find each matching F-Curve for the variables we're interested in */
+ while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) {
+ FCurve *fcu= (FCurve *)ld->data;
+
+ /* assign this F-Curve to one of the relevant pointers... */
+ switch (fcu->array_index) {
+ case 3: /* z */
+ fcu_z= fcu;
+ break;
+ case 2: /* y */
+ fcu_y= fcu;
+ break;
+ case 1: /* x */
+ fcu_x= fcu;
+ break;
+ case 0: /* w */
+ fcu_w= fcu;
+ break;
+ }
+ }
+
+ /* only if all channels exist, proceed */
+ if (fcu_w && fcu_x && fcu_y && fcu_z) {
+ float quat_prev[4], quat_next[4];
+
+ /* get 2 quats */
+ quat_prev[0] = evaluate_fcurve(fcu_w, pso->prevFrame);
+ quat_prev[1] = evaluate_fcurve(fcu_x, pso->prevFrame);
+ quat_prev[2] = evaluate_fcurve(fcu_y, pso->prevFrame);
+ quat_prev[3] = evaluate_fcurve(fcu_z, pso->prevFrame);
+
+ quat_next[0] = evaluate_fcurve(fcu_w, pso->nextFrame);
+ quat_next[1] = evaluate_fcurve(fcu_x, pso->nextFrame);
+ quat_next[2] = evaluate_fcurve(fcu_y, pso->nextFrame);
+ quat_next[3] = evaluate_fcurve(fcu_z, pso->nextFrame);
+
+ /* perform blending */
+ if (pso->mode == POSESLIDE_BREAKDOWN) {
+ /* just perform the interpol between quat_prev and quat_next using pso->percentage as a guide */
+ QuatInterpol(pchan->quat, quat_prev, quat_next, pso->percentage);
+ }
+ else {
+ float quat_interp[4], quat_orig[4];
+ int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+
+ /* perform this blending several times until a satisfactory result is reached */
+ while (iters-- > 0) {
+ /* calculate the interpolation between the endpoints */
+ QuatInterpol(quat_interp, quat_prev, quat_next, (cframe-pso->prevFrame) / (pso->nextFrame-pso->prevFrame) );
+
+ /* make a copy of the original rotation */
+ QUATCOPY(quat_orig, pchan->quat);
+
+ /* tricky interpolations - mode-dependent blending between original and new */
+ if (pso->mode == POSESLIDE_RELAX) // xxx this was the original code, so should work fine
+ QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
+ else // I'm just guessing here...
+ QuatInterpol(pchan->quat, quat_orig, quat_interp, 6.0f/5.0f);
+ }
+ }
+ }
+
+ /* free the path now */
+ MEM_freeN(path);
}
/* apply() - perform the pose sliding based on weighting various poses */