[Bf-blender-cvs] [677d2e2] PSketch: PSculpt: Autokeying Support
Joshua Leung
noreply at git.blender.org
Sun Jan 31 14:29:27 CET 2016
Commit: 677d2e20b4a1d612c6c0b44a9cf0629d598f7253
Author: Joshua Leung
Date: Tue Jan 26 02:45:55 2016 +1300
Branches: PSketch
https://developer.blender.org/rB677d2e20b4a1d612c6c0b44a9cf0629d598f7253
PSculpt: Autokeying Support
When autokeying is enabled, bones will automatically be keyed using the
"Whole Character" Keying Set.
TODO:
* Add support for only doing partial keying - perhaps by having options
for controlling what gets used to do this?
===================================================================
M source/blender/editors/armature/pose_sculpt.c
===================================================================
diff --git a/source/blender/editors/armature/pose_sculpt.c b/source/blender/editors/armature/pose_sculpt.c
index f67ac72..835be6d 100644
--- a/source/blender/editors/armature/pose_sculpt.c
+++ b/source/blender/editors/armature/pose_sculpt.c
@@ -48,6 +48,7 @@
#include "BLI_threads.h"
#include "BLI_rand.h"
+#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
@@ -64,6 +65,7 @@
#include "BIF_glutil.h"
#include "ED_armature.h"
+#include "ED_keyframing.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_view3d.h"
@@ -201,7 +203,8 @@ typedef struct tAffectedBone {
bPoseChannel *pchan; /* bone in question */
float fac; /* (last) strength factor applied to this bone */
- // TODO: unaffected transforms
+ // TODO: original bone values?
+ // TODO: bitflag for which channels need keying
} tAffectedBone;
/* Pose Sculpting brush operator data */
@@ -218,6 +221,9 @@ typedef struct tPoseSculptingOp {
wmTimer *timer; /* timer for in-place accumulation of brush effect */
GHash *affected_bones; /* list of bones affected by brush */
+
+ KeyingSet *ks; /* keyingset to use */
+ ListBase ks_sources; /* list of elements to be keyed by the Keying Set */
} tPoseSculptingOp;
/* Callback Function Signature */
@@ -651,7 +657,7 @@ static void apply_pchan_joints(bPoseChannel *pchan, float dvec[3])
/* ........................................................ */
/* check if a bone has already been affected by the brush, and add an entry if not */
-static tAffectedBone *verify_bone_is_affected(tPoseSculptingOp *pso, tPSculptContext *data, bPoseChannel *pchan, short add)
+static tAffectedBone *verify_bone_is_affected(tPoseSculptingOp *pso, tPSculptContext *data, bPoseChannel *pchan, bool add)
{
/* try to find bone */
tAffectedBone *tab = BLI_ghash_lookup(pso->affected_bones, pchan);
@@ -765,7 +771,7 @@ static void psculpt_brush_calc_trackball(tPoseSculptingOp *pso, tPSculptContext
float mat[3][3], refmat[3][3];
float axis1[3], axis2[3];
float angles[2];
-
+
/* Compute screenspace movements for trackball transform
* Adapted from applyTrackball() in transform.c
@@ -774,19 +780,19 @@ static void psculpt_brush_calc_trackball(tPoseSculptingOp *pso, tPSculptContext
copy_v3_v3(axis2, rv3d->persinv[1]);
normalize_v3(axis1);
normalize_v3(axis2);
-
+
/* From InputTrackBall() in transform_input.c */
angles[0] = (float)(pso->lastmouse[1] - data->mval[1]);
angles[1] = (float)(data->mval[0] - pso->lastmouse[0]);
-
+
mul_v2_fl(angles, 0.01f); /* (mi->factor = 0.01f) */
-
+
/* Adapted from applyTrackballValue() in transform.c */
axis_angle_normalized_to_mat3(smat, axis1, angles[0]);
axis_angle_normalized_to_mat3(totmat, axis2, angles[1]);
-
+
mul_m3_m3m3(mat, smat, totmat);
-
+
/* Adjust strength of effect */
unit_m3(refmat);
interp_m3_m3m3(data->rmat, refmat, mat, brush->strength);
@@ -1007,6 +1013,14 @@ static int psculpt_brush_init(bContext *C, wmOperator *op)
data->is_first = true;
+ /* init data needed for handling autokeying
+ * - If autokeying is not applicable here, the keyingset will be NULL,
+ * and therefore no autokeying stuff will need to happen later...
+ */
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+ pso->ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
+ }
+
/* setup cursor and header drawing */
ED_area_headerprint(CTX_wm_area(C), IFACE_("Pose Sculpting in progress..."));
@@ -1042,6 +1056,30 @@ static void psculpt_brush_exit(bContext *C, wmOperator *op)
/* Apply ----------------------------------------------- */
+/* Perform auto-keyframing */
+static void psculpt_brush_do_autokey(bContext *C, tPoseSculptingOp *pso)
+{
+ BLI_assert(pso->ks != NULL);
+
+ if (pso->ks && pso->ks_sources.first) {
+ Scene *scene = pso->scene;
+ Object *ob = pso->ob;
+
+ /* insert keyframes for all relevant bones in one go */
+ ANIM_apply_keyingset(C, &pso->ks_sources, NULL, pso->ks, MODIFYKEY_MODE_INSERT, CFRA);
+ BLI_freelistN(&pso->ks_sources);
+
+ /* do the bone paths
+ * - only do this if keyframes should have been added
+ * - do not calculate unless there are paths already to update...
+ */
+ if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) {
+ //ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear
+ ED_pose_recalculate_paths(scene, ob);
+ }
+ }
+}
+
/* Apply brush callback on bones which fall within the brush region
* Based on method pose_circle_select() in view3d_select.c
*/
@@ -1049,8 +1087,9 @@ static bool psculpt_brush_do_apply(tPoseSculptingOp *pso, tPSculptContext *data,
{
PSculptSettings *pset = psculpt_settings(pso->scene);
ViewContext *vc = &data->vc;
- bArmature *arm = data->ob->data;
- bPose *pose = data->ob->pose;
+ Object *ob = data->ob;
+ bArmature *arm = ob->data;
+ bPose *pose = ob->pose;
bPoseChannel *pchan;
bool changed = false;
@@ -1092,20 +1131,22 @@ static bool psculpt_brush_do_apply(tPoseSculptingOp *pso, tPSculptContext *data,
continue;
}
- /* check if the head and/or tail is in the circle
- * - the call to check also does the selection already
+ /* Check if this is already in the cache for a brush that just wants to affect those initially captured;
+ * If that's the case, we should just continue to affect it
*/
- // FIXME: this method FAILS on custom bones shapes. Can be quite bad sometimes with production rigs!
- if (edge_inside_circle(data->mval, data->rad, sco1, sco2)) {
- ok = true;
- }
- /* alternatively, check if this is already in the cache for a brush that just wants to affect those initially captured */
else if ((data->brush->flag & PSCULPT_BRUSH_FLAG_GRAB_INITIAL) &&
(data->is_first == false) &&
(verify_bone_is_affected(pso, data, pchan, false) != NULL))
{
ok = true;
}
+ /* Otherwise, check if the head and/or tail is in the circle
+ * - the call to check also does the selection already
+ */
+ // FIXME: this method FAILS on custom bones shapes. Can be quite bad sometimes with production rigs!
+ else if (edge_inside_circle(data->mval, data->rad, sco1, sco2)) {
+ ok = true;
+ }
/* act on bone? */
if (ok) {
@@ -1118,6 +1159,15 @@ static bool psculpt_brush_do_apply(tPoseSculptingOp *pso, tPSculptContext *data,
/* apply callback to this bone */
brush_cb(pso, data, pchan, sco1, sco2);
+ /* schedule this bone up for being keyframed (if autokeying is enabled) */
+ if (pso->ks) {
+ ANIM_relative_keyingset_add_source(&pso->ks_sources, &ob->id, &RNA_PoseBone, pchan);
+ if (pchan->bone) pchan->bone->flag &= ~BONE_UNKEYED;
+ }
+ else {
+ if (pchan->bone) pchan->bone->flag |= BONE_UNKEYED;
+ }
+
/* tag as changed */
// TODO: add to autokeying cache...
changed |= true;
@@ -1300,6 +1350,10 @@ static void psculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr
if (changed) {
bArmature *arm = (bArmature *)ob->data;
+ /* perform autokeying first */
+ // XXX: order?
+ psculpt_brush_do_autokey(C, pso);
+
/* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
More information about the Bf-blender-cvs
mailing list