diff options
author | Joshua Leung <aligorith@gmail.com> | 2013-02-28 04:01:20 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2013-02-28 04:01:20 +0400 |
commit | dff8c01c3eb712ccc96d59037f3e4a5b63f63c21 (patch) | |
tree | eafcbe35d7ee57a329c8ba348db52d833e465ae8 /source/blender/editors/armature/pose_utils.c | |
parent | e8d42ab48e42390eb43ee8905cf0c3adb1e0e3a1 (diff) |
Renaming the remaining PoseMode files for consistency (camelCase to
underscores_style)
Diffstat (limited to 'source/blender/editors/armature/pose_utils.c')
-rw-r--r-- | source/blender/editors/armature/pose_utils.c | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c new file mode 100644 index 00000000000..4361fa96153 --- /dev/null +++ b/source/blender/editors/armature/pose_utils.c @@ -0,0 +1,283 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/armature/pose_utils.c + * \ingroup edarmature + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> +#include <string.h> +#include <math.h> +#include <float.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_dynstr.h" +#include "BLI_dlrbTree.h" +#include "BLI_utildefines.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_depsgraph.h" +#include "BKE_idprop.h" + +#include "BKE_context.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + + + +#include "ED_armature.h" +#include "ED_keyframing.h" + +#include "armature_intern.h" + +/* *********************************************** */ +/* Contents of this File: + * + * This file contains methods shared between Pose Slide and Pose Lib; + * primarily the functions in question concern Animato <-> Pose + * convenience functions, such as applying/getting pose values + * and/or inserting keyframes for these. + */ +/* *********************************************** */ +/* FCurves <-> PoseChannels Links */ + +/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */ +static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *act, bPoseChannel *pchan) +{ + ListBase curves = {NULL, NULL}; + int transFlags = action_get_item_transforms(act, ob, pchan, &curves); + + pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE); + + /* check if any transforms found... */ + if (transFlags) { + /* make new linkage data */ + tPChanFCurveLink *pfl = MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink"); + PointerRNA ptr; + + pfl->fcurves = curves; + pfl->pchan = pchan; + + /* get the RNA path to this pchan - this needs to be freed! */ + RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr); + pfl->pchan_path = RNA_path_from_ID_to_struct(&ptr); + + /* add linkage data to operator data */ + BLI_addtail(pfLinks, pfl); + + /* set pchan's transform flags */ + if (transFlags & ACT_TRANS_LOC) + pchan->flag |= POSE_LOC; + if (transFlags & ACT_TRANS_ROT) + pchan->flag |= POSE_ROT; + if (transFlags & ACT_TRANS_SCALE) + pchan->flag |= POSE_SIZE; + + /* store current transforms */ + copy_v3_v3(pfl->oldloc, pchan->loc); + copy_v3_v3(pfl->oldrot, pchan->eul); + copy_v3_v3(pfl->oldscale, pchan->size); + copy_qt_qt(pfl->oldquat, pchan->quat); + copy_v3_v3(pfl->oldaxis, pchan->rotAxis); + pfl->oldangle = pchan->rotAngle; + + /* make copy of custom properties */ + if (pchan->prop && (transFlags & ACT_TRANS_PROP)) + pfl->oldprops = IDP_CopyProperty(pchan->prop); + } +} + + +/* get sets of F-Curves providing transforms for the bones in the Pose */ +void poseAnim_mapping_get(bContext *C, ListBase *pfLinks, Object *ob, bAction *act) +{ + /* for each Pose-Channel which gets affected, get the F-Curves for that channel + * and set the relevant transform flags... + */ + CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) + { + fcurves_to_pchan_links_get(pfLinks, ob, act, pchan); + } + CTX_DATA_END; + + /* if no PoseChannels were found, try a second pass, doing visible ones instead + * i.e. if nothing selected, do whole pose + */ + if (pfLinks->first == NULL) { + CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) + { + fcurves_to_pchan_links_get(pfLinks, ob, act, pchan); + } + CTX_DATA_END; + } +} + +/* free F-Curve <-> PoseChannel links */ +void poseAnim_mapping_free(ListBase *pfLinks) +{ + tPChanFCurveLink *pfl, *pfln = NULL; + + /* free the temp pchan links and their data */ + for (pfl = pfLinks->first; pfl; pfl = pfln) { + pfln = pfl->next; + + /* free custom properties */ + if (pfl->oldprops) { + IDP_FreeProperty(pfl->oldprops); + MEM_freeN(pfl->oldprops); + } + + /* free list of F-Curve reference links */ + BLI_freelistN(&pfl->fcurves); + + /* free pchan RNA Path */ + MEM_freeN(pfl->pchan_path); + + /* free link itself */ + BLI_freelinkN(pfLinks, pfl); + } +} + +/* ------------------------- */ + +/* helper for apply() / reset() - refresh the data */ +void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob) +{ + bArmature *arm = (bArmature *)ob->data; + + /* old optimize trick... this enforces to bypass the depgraph + * - note: code copied from transform_generics.c -> recalcData() + */ + /* FIXME: shouldn't this use the builtin stuff? */ + if ((arm->flag & ARM_DELAYDEFORM) == 0) + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ + else + BKE_pose_where_is(scene, ob); + + /* note, notifier might evolve */ + WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); +} + +/* reset changes made to current pose */ +void poseAnim_mapping_reset(ListBase *pfLinks) +{ + tPChanFCurveLink *pfl; + + /* iterate over each pose-channel affected, restoring all channels to their original values */ + for (pfl = pfLinks->first; pfl; pfl = pfl->next) { + bPoseChannel *pchan = pfl->pchan; + + /* just copy all the values over regardless of whether they changed or not */ + copy_v3_v3(pchan->loc, pfl->oldloc); + copy_v3_v3(pchan->eul, pfl->oldrot); + copy_v3_v3(pchan->size, pfl->oldscale); + copy_qt_qt(pchan->quat, pfl->oldquat); + copy_v3_v3(pchan->rotAxis, pfl->oldaxis); + pchan->rotAngle = pfl->oldangle; + + /* just overwrite values of properties from the stored copies (there should be some) */ + if (pfl->oldprops) + IDP_SyncGroupValues(pfl->pchan->prop, pfl->oldprops); + } +} + +/* perform autokeyframing after changes were made + confirmed */ +void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBase *pfLinks, float cframe) +{ + /* insert keyframes as necessary if autokeyframing */ + if (autokeyframe_cfra_can_key(scene, &ob->id)) { + KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID); + ListBase dsources = {NULL, NULL}; + tPChanFCurveLink *pfl; + + /* iterate over each pose-channel affected, tagging bones to be keyed */ + /* XXX: here we already have the information about what transforms exist, though + * it might be easier to just overwrite all using normal mechanisms + */ + for (pfl = pfLinks->first; pfl; pfl = pfl->next) { + bPoseChannel *pchan = pfl->pchan; + + /* add datasource override for the PoseChannel, to be used later */ + ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan); + + /* clear any unkeyed tags */ + if (pchan->bone) + pchan->bone->flag &= ~BONE_UNKEYED; + } + + /* insert keyframes for all relevant bones in one go */ + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cframe); + BLI_freelistN(&dsources); + + /* do the bone paths + * - only do this if keyframes should have been added + * - do not calculate unless there are paths already to update... + */ + if (C && (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); + } + } +} + +/* ------------------------- */ + +/* find the next F-Curve for a PoseChannel with matching path... + * - path is not just the pfl rna_path, since that path doesn't have property info yet + */ +LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, const char *path) +{ + LinkData *first = (prev) ? prev->next : (fcuLinks) ? fcuLinks->first : NULL; + LinkData *ld; + + /* check each link to see if the linked F-Curve has a matching path */ + for (ld = first; ld; ld = ld->next) { + FCurve *fcu = (FCurve *)ld->data; + + /* check if paths match */ + if (strcmp(path, fcu->rna_path) == 0) + return ld; + } + + /* none found */ + return NULL; +} + +/* *********************************************** */ |