[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35513] trunk/blender/source/blender: Pose Sliding Tools - Custom Property Support + Other bugfixes
Joshua Leung
aligorith at gmail.com
Sun Mar 13 13:22:57 CET 2011
Revision: 35513
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35513
Author: aligorith
Date: 2011-03-13 12:22:57 +0000 (Sun, 13 Mar 2011)
Log Message:
-----------
Pose Sliding Tools - Custom Property Support + Other bugfixes
- Custom properties are now affected by the Pose Sliding tools too.
This is now more important to support, given that modern rigs use
these a lot for facial expressions/posing. By and large, this should
work fine, though discrete integer values may experience a bit of
trouble
- Fixed potential bugs with the code which detects which F-Curves are
relevant to a PoseBone's transforms (+ custom props). This was prone
to being tricked by certain setups if the names of the bones contained
some of the keywords these were searching for.
- Shuffled some code around: moved bulk of logic out of vec3 case into
new function for single-value, since it was really doing per axis
already
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/BKE_action.h
trunk/blender/source/blender/blenkernel/intern/action.c
trunk/blender/source/blender/editors/armature/armature_intern.h
trunk/blender/source/blender/editors/armature/poseSlide.c
trunk/blender/source/blender/editors/armature/poseUtils.c
Modified: trunk/blender/source/blender/blenkernel/BKE_action.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_action.h 2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/blenkernel/BKE_action.h 2011-03-13 12:22:57 UTC (rev 35513)
@@ -82,9 +82,15 @@
ACT_TRANS_ROT = (1<<1),
/* scaling */
ACT_TRANS_SCALE = (1<<2),
+
+ /* strictly not a transform, but custom properties are also
+ * quite often used in modern rigs
+ */
+ ACT_TRANS_PROP = (1<<3),
/* all flags */
- ACT_TRANS_ALL = (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE),
+ ACT_TRANS_ONLY = (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE),
+ ACT_TRANS_ALL = (ACT_TRANS_ONLY|ACT_TRANS_PROP)
} eAction_TransformFlags;
/* Return flags indicating which transforms the given object/posechannel has
Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c 2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/blenkernel/intern/action.c 2011-03-13 12:22:57 UTC (rev 35513)
@@ -973,6 +973,11 @@
bPtr= strstr(fcu->rna_path, basePath);
if (bPtr) {
+ /* we must add len(basePath) bytes to the match so that we are at the end of the
+ * base path so that we don't get false positives with these strings in the names
+ */
+ bPtr += strlen(basePath);
+
/* step 2: check for some property with transforms
* - to speed things up, only check for the ones not yet found
* unless we're getting the curves too
@@ -981,8 +986,8 @@
* - once a match has been found, the curve cannot possibly be any other one
*/
if ((curves) || (flags & ACT_TRANS_LOC) == 0) {
- pPtr= strstr(fcu->rna_path, "location");
- if ((pPtr) && (pPtr >= bPtr)) {
+ pPtr= strstr(bPtr, "location");
+ if (pPtr) {
flags |= ACT_TRANS_LOC;
if (curves)
@@ -992,8 +997,8 @@
}
if ((curves) || (flags & ACT_TRANS_SCALE) == 0) {
- pPtr= strstr(fcu->rna_path, "scale");
- if ((pPtr) && (pPtr >= bPtr)) {
+ pPtr= strstr(bPtr, "scale");
+ if (pPtr) {
flags |= ACT_TRANS_SCALE;
if (curves)
@@ -1003,8 +1008,8 @@
}
if ((curves) || (flags & ACT_TRANS_ROT) == 0) {
- pPtr= strstr(fcu->rna_path, "rotation");
- if ((pPtr) && (pPtr >= bPtr)) {
+ pPtr= strstr(bPtr, "rotation");
+ if (pPtr) {
flags |= ACT_TRANS_ROT;
if (curves)
@@ -1012,6 +1017,18 @@
continue;
}
}
+
+ if ((curves) || (flags & ACT_TRANS_PROP) == 0) {
+ /* custom properties only */
+ pPtr= strstr(bPtr, "[\""); /* extra '"' comment here to keep my texteditor functionlist working :) */
+ if (pPtr) {
+ flags |= ACT_TRANS_PROP;
+
+ if (curves)
+ BLI_addtail(curves, BLI_genericNodeN(fcu));
+ continue;
+ }
+ }
}
}
Modified: trunk/blender/source/blender/editors/armature/armature_intern.h
===================================================================
--- trunk/blender/source/blender/editors/armature/armature_intern.h 2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/editors/armature/armature_intern.h 2011-03-13 12:22:57 UTC (rev 35513)
@@ -150,16 +150,19 @@
typedef struct tPChanFCurveLink {
struct tPChanFCurveLink *next, *prev;
- ListBase fcurves; /* F-Curves for this PoseChannel (wrapped with LinkData) */
- struct bPoseChannel *pchan; /* Pose Channel which data is attached to */
+ ListBase fcurves; /* F-Curves for this PoseChannel (wrapped with LinkData) */
+ struct bPoseChannel *pchan; /* Pose Channel which data is attached to */
- char *pchan_path; /* RNA Path to this Pose Channel (needs to be freed when we're done) */
+ char *pchan_path; /* RNA Path to this Pose Channel (needs to be freed when we're done) */
- // TODO: need to include axis-angle here at some stage
- float oldloc[3]; /* transform values at start of operator (to be restored before each modal step) */
+ float oldloc[3]; /* transform values at start of operator (to be restored before each modal step) */
float oldrot[3];
float oldscale[3];
float oldquat[4];
+ float oldangle;
+ float oldaxis[3];
+
+ struct IDProperty *oldprops; /* copy of custom properties at start of operator (to be restored before each modal step) */
} tPChanFCurveLink;
/* ----------- */
Modified: trunk/blender/source/blender/editors/armature/poseSlide.c
===================================================================
--- trunk/blender/source/blender/editors/armature/poseSlide.c 2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/editors/armature/poseSlide.c 2011-03-13 12:22:57 UTC (rev 35513)
@@ -192,102 +192,146 @@
poseAnim_mapping_refresh(C, pso->scene, pso->ob);
}
+/* helper for apply() - perform sliding for some value */
+static void pose_slider_apply_val (tPoseSlideOp *pso, FCurve *fcu, float *val)
+{
+ float cframe = (float)pso->cframe;
+ float sVal, eVal;
+ float w1, w2;
+
+ /* get keyframe values for endpoint poses to blend with */
+ /* previous/start */
+ sVal= evaluate_fcurve(fcu, (float)pso->prevFrame);
+ /* next/end */
+ eVal= evaluate_fcurve(fcu, (float)pso->nextFrame);
+
+ /* calculate the relative weights of the endpoints */
+ if (pso->mode == POSESLIDE_BREAKDOWN) {
+ /* get weights from the percentage control */
+ w1= pso->percentage; /* this must come second */
+ w2= 1.0f - w1; /* this must come first */
+ }
+ else {
+ /* - these weights are derived from the relative distance of these
+ * poses from the current frame
+ * - they then get normalised so that they only sum up to 1
+ */
+ float wtot;
+
+ w1 = cframe - (float)pso->prevFrame;
+ w2 = (float)pso->nextFrame - cframe;
+
+ wtot = w1 + w2;
+ w1 = (w1/wtot);
+ w2 = (w2/wtot);
+ }
+
+ /* depending on the mode, calculate the new value
+ * - in all of these, the start+end values are multiplied by w2 and w1 (respectively),
+ * since multiplication in another order would decrease the value the current frame is closer to
+ */
+ switch (pso->mode) {
+ case POSESLIDE_PUSH: /* make the current pose more pronounced */
+ {
+ /* perform a weighted average here, favouring the middle pose
+ * - numerator should be larger than denominator to 'expand' the result
+ * - perform this weighting a number of times given by the percentage...
+ */
+ int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+
+ while (iters-- > 0) {
+ (*val)= ( -((sVal * w2) + (eVal * w1)) + ((*val) * 6.0f) ) / 5.0f;
+ }
+ }
+ break;
+
+ case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */
+ {
+ /* perform a weighted average here, favouring the middle pose
+ * - numerator should be smaller than denominator to 'relax' the result
+ * - perform this weighting a number of times given by the percentage...
+ */
+ int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+
+ while (iters-- > 0) {
+ (*val)= ( ((sVal * w2) + (eVal * w1)) + ((*val) * 5.0f) ) / 6.0f;
+ }
+ }
+ break;
+
+ case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */
+ {
+ /* perform simple linear interpolation - coefficient for start must come from pso->percentage... */
+ // TODO: make this use some kind of spline interpolation instead?
+ (*val)= ((sVal * w2) + (eVal * w1));
+ }
+ break;
+ }
+}
+
/* helper for apply() - perform sliding for some 3-element vector */
-static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, float vec[3], const char *propName)
+static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, float vec[3], const char propName[])
{
LinkData *ld=NULL;
char *path=NULL;
- float cframe;
/* get the path to use... */
path= BLI_sprintfN("%s.%s", pfl->pchan_path, propName);
- /* 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= poseAnim_mapping_getNextFCurve(&pfl->fcurves, ld, path)) ) {
FCurve *fcu= (FCurve *)ld->data;
- float sVal, eVal;
- float w1, w2;
- int ch;
- /* get keyframe values for endpoint poses to blend with */
- /* previous/start */
- sVal= evaluate_fcurve(fcu, (float)pso->prevFrame);
- /* next/end */
- eVal= evaluate_fcurve(fcu, (float)pso->nextFrame);
+ /* just work on these channels one by one... there's no interaction between values */
+ pose_slider_apply_val(pso, fcu, &vec[fcu->array_index]);
+ }
+
+ /* free the temp path we got */
+ MEM_freeN(path);
+}
+
+/* helper for apply() - perform sliding for custom properties */
+static void pose_slide_apply_props (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
+{
+ PointerRNA ptr = {{NULL}};
+ LinkData *ld;
+ int len = strlen(pfl->pchan_path);
+
+ /* setup pointer RNA for resolving paths */
+ RNA_pointer_create(NULL, &RNA_PoseBone, pfl->pchan, &ptr);
+
+ /* custom properties are just denoted using ["..."][etc.] after the end of the base path,
+ * so just check for opening pair after the end of the path
+ */
+ for (ld = pfl->fcurves.first; ld; ld = ld->next) {
+ FCurve *fcu = (FCurve *)ld->data;
+ char *bPtr, *pPtr;
- /* get channel index */
- ch= fcu->array_index;
+ if (fcu->rna_path == NULL)
+ continue;
- /* calculate the relative weights of the endpoints */
- if (pso->mode == POSESLIDE_BREAKDOWN) {
- /* get weights from the percentage control */
- w1= pso->percentage; /* this must come second */
- w2= 1.0f - w1; /* this must come first */
- }
- else {
- /* - these weights are derived from the relative distance of these
- * poses from the current frame
- * - they then get normalised so that they only sum up to 1
+ /* do we have a match?
+ * - bPtr is the RNA Path with the standard part chopped off
+ * - pPtr is the chunk of the path which is left over
+ */
+ bPtr = strstr(fcu->rna_path, pfl->pchan_path) + len;
+ pPtr = strstr(bPtr, "[\""); /* dummy " for texteditor bugs */
+
+ if (pPtr) {
+ /* use RNA to try and get a handle on this property, then, assuming that it is just
+ * numerical, try and grab the value as a float for temp editing before setting back
*/
- float wtot;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list