4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
24 * Full recode, Joshua Leung, 2009
26 * ***** END GPL LICENSE BLOCK *****
38 #include "MEM_guardedalloc.h"
40 #include "DNA_anim_types.h"
41 #include "DNA_armature_types.h"
42 #include "DNA_constraint_types.h"
43 #include "DNA_scene_types.h"
45 #include "BKE_animsys.h"
46 #include "BKE_action.h"
48 #include "BKE_constraint.h"
49 #include "BKE_global.h"
50 #include "BKE_fcurve.h"
51 #include "BKE_library.h"
53 #include "BKE_object.h"
54 #include "BKE_utildefines.h"
55 #include "BKE_idprop.h"
60 #include "BLI_blenlib.h"
62 #include "RNA_access.h"
64 /* *********************** NOTE ON POSE AND ACTION **********************
66 - Pose is the local (object level) component of armature. The current
67 object pose is saved in files, and (will be) is presorted for dependency
68 - Actions have fewer (or other) channels, and write data to a Pose
69 - Currently ob->pose data is controlled in where_is_pose only. The (recalc)
70 event system takes care of calling that
71 - The NLA system (here too) uses Poses as interpolation format for Actions
72 - Therefore we assume poses to be static, and duplicates of poses have channels in
73 same order, for quick interpolation reasons
75 ****************************** (ton) ************************************ */
77 /* ***************** Library data level operations on action ************** */
79 bAction *add_empty_action(const char name[])
83 act= alloc_libblock(&G.main->action, ID_AC, name);
84 act->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
90 // does copy_fcurve...
91 void make_local_action(bAction *act)
97 if (act->id.lib==0) return;
100 act->id.flag= LIB_LOCAL;
101 //make_local_action_channels(act);
102 new_id(0, (ID *)act, 0);
106 #if 0 // XXX old animation system
107 ob= G.main->object.first;
109 if(ob->action==act) {
110 if(ob->id.lib) lib= 1;
117 if(local && lib==0) {
119 act->id.flag= LIB_LOCAL;
120 //make_local_action_channels(act);
121 new_id(0, (ID *)act, 0);
123 else if(local && lib) {
124 actn= copy_action(act);
127 #if 0 // XXX old animation system
128 ob= G.main->object.first;
130 if(ob->action==act) {
140 #endif // XXX old animation system
144 void free_action (bAction *act)
151 free_fcurves(&act->curves);
154 if (act->groups.first)
155 BLI_freelistN(&act->groups);
157 /* Free pose-references (aka local markers) */
158 if (act->markers.first)
159 BLI_freelistN(&act->markers);
162 bAction *copy_action (bAction *src)
165 bActionGroup *dgrp, *sgrp;
170 dst= copy_libblock(src);
172 /* duplicate the lists of groups and markers */
173 BLI_duplicatelist(&dst->groups, &src->groups);
174 BLI_duplicatelist(&dst->markers, &src->markers);
176 /* copy F-Curves, fixing up the links as we go */
177 dst->curves.first= dst->curves.last= NULL;
179 for (sfcu= src->curves.first; sfcu; sfcu= sfcu->next) {
180 /* duplicate F-Curve */
181 dfcu= copy_fcurve(sfcu);
182 BLI_addtail(&dst->curves, dfcu);
184 /* fix group links (kindof bad list-in-list search, but this is the most reliable way) */
185 for (dgrp=dst->groups.first, sgrp=src->groups.first; dgrp && sgrp; dgrp=dgrp->next, sgrp=sgrp->next) {
186 if (sfcu->grp == sgrp) {
189 if (dgrp->channels.first == sfcu)
190 dgrp->channels.first= dfcu;
191 if (dgrp->channels.last == sfcu)
192 dgrp->channels.last= dfcu;
199 dst->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
205 /* *************** Action Groups *************** */
207 /* Get the active action-group for an Action */
208 bActionGroup *get_active_actiongroup (bAction *act)
210 bActionGroup *agrp= NULL;
212 if (act && act->groups.first) {
213 for (agrp= act->groups.first; agrp; agrp= agrp->next) {
214 if (agrp->flag & AGRP_ACTIVE)
222 /* Make the given Action-Group the active one */
223 void set_active_action_group (bAction *act, bActionGroup *agrp, short select)
231 /* Deactive all others */
232 for (grp= act->groups.first; grp; grp= grp->next) {
233 if ((grp==agrp) && (select))
234 grp->flag |= AGRP_ACTIVE;
236 grp->flag &= ~AGRP_ACTIVE;
240 /* Add given channel into (active) group
241 * - assumes that channel is not linked to anything anymore
242 * - always adds at the end of the group
244 void action_groups_add_channel (bAction *act, bActionGroup *agrp, FCurve *fcurve)
247 if (ELEM3(NULL, act, agrp, fcurve))
250 /* if no channels anywhere, just add to two lists at the same time */
251 if (act->curves.first == NULL) {
252 fcurve->next = fcurve->prev = NULL;
254 agrp->channels.first = agrp->channels.last = fcurve;
255 act->curves.first = act->curves.last = fcurve;
258 /* if the group already has channels, the F-Curve can simply be added to the list
259 * (i.e. as the last channel in the group)
261 else if (agrp->channels.first) {
262 /* if the group's last F-Curve is the action's last F-Curve too,
263 * then set the F-Curve as the last for the action first so that
264 * the lists will be in sync after linking
266 if (agrp->channels.last == act->curves.last)
267 act->curves.last= fcurve;
269 /* link in the given F-Curve after the last F-Curve in the group,
270 * which means that it should be able to fit in with the rest of the
273 BLI_insertlinkafter(&agrp->channels, agrp->channels.last, fcurve);
276 /* otherwise, need to find the nearest F-Curve in group before/after current to link with */
280 /* firstly, link this F-Curve to the group */
281 agrp->channels.first = agrp->channels.last = fcurve;
283 /* step through the groups preceeding this one, finding the F-Curve there to attach this one after */
284 for (grp= agrp->prev; grp; grp= grp->prev) {
285 /* if this group has F-Curves, we want weave the given one in right after the last channel there,
286 * but via the Action's list not this group's list
287 * - this is so that the F-Curve is in the right place in the Action,
288 * but won't be included in the previous group
290 if (grp->channels.last) {
291 /* once we've added, break here since we don't need to search any further... */
292 BLI_insertlinkafter(&act->curves, grp->channels.last, fcurve);
297 /* if grp is NULL, that means we fell through, and this F-Curve should be added as the new first
298 * since group is (effectively) the first group. Thus, the existing first F-Curve becomes the
299 * second in the chain, etc. etc.
302 BLI_insertlinkbefore(&act->curves, act->curves.first, fcurve);
305 /* set the F-Curve's new group */
309 /* Remove the given channel from all groups */
310 void action_groups_remove_channel (bAction *act, FCurve *fcu)
313 if (ELEM(NULL, act, fcu))
316 /* check if any group used this directly */
318 bActionGroup *agrp= fcu->grp;
320 if (agrp->channels.first == agrp->channels.last) {
321 if (agrp->channels.first == fcu) {
322 agrp->channels.first= NULL;
323 agrp->channels.last= NULL;
326 else if (agrp->channels.first == fcu) {
327 if ((fcu->next) && (fcu->next->grp==agrp))
328 agrp->channels.first= fcu->next;
330 agrp->channels.first= NULL;
332 else if (agrp->channels.last == fcu) {
333 if ((fcu->prev) && (fcu->prev->grp==agrp))
334 agrp->channels.last= fcu->prev;
336 agrp->channels.last= NULL;
342 /* now just remove from list */
343 BLI_remlink(&act->curves, fcu);
346 /* Find a group with the given name */
347 bActionGroup *action_groups_find_named (bAction *act, const char name[])
352 if (ELEM3(NULL, act, act->groups.first, name) || (name[0] == 0))
355 /* do string comparisons */
356 for (grp= act->groups.first; grp; grp= grp->next) {
357 if (strcmp(grp->name, name) == 0)
365 /* *************** Pose channels *************** */
367 /* usually used within a loop, so we got a N^2 slowdown */
368 bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
370 if (ELEM(NULL, pose, name) || (name[0] == 0))
373 return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
376 /* Use with care, not on Armature poses but for temporal ones */
377 /* (currently used for action constraints and in rebuild_pose) */
378 bPoseChannel *verify_pose_channel(bPose *pose, const char *name)
385 /* See if this channel exists */
386 for (chan=pose->chanbase.first; chan; chan=chan->next) {
387 if (!strcmp (name, chan->name))
391 /* If not, create it and add it */
392 chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
394 strncpy(chan->name, name, 31);
395 /* init vars to prevent math errors */
396 chan->quat[0] = chan->rotAxis[1]= 1.0f;
397 chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
399 chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f;
400 chan->limitmax[0]= chan->limitmax[1]= chan->limitmax[2]= 180.0f;
401 chan->stiffness[0]= chan->stiffness[1]= chan->stiffness[2]= 0.0f;
402 chan->ikrotweight = chan->iklinweight = 0.0f;
403 unit_m4(chan->constinv);
405 chan->protectflag = OB_LOCK_ROT4D; /* lock by components by default */
407 BLI_addtail(&pose->chanbase, chan);
412 /* Find the active posechannel for an object (we can't just use pose, as layer info is in armature) */
413 bPoseChannel *get_active_posechannel (Object *ob)
415 bArmature *arm= (ob) ? ob->data : NULL;
418 if ELEM3(NULL, ob, ob->pose, arm)
422 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
423 if ((pchan->bone) && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer))
430 const char *get_ikparam_name(bPose *pose)
433 switch (pose->iksolver) {
434 case IKSOLVER_LEGACY:
442 /* dst should be freed already, makes entire duplicate */
443 void copy_pose (bPose **dst, bPose *src, int copycon)
455 printf("copy_pose source and target are the same\n");
460 outPose= MEM_callocN(sizeof(bPose), "pose");
462 BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
464 outPose->iksolver = src->iksolver;
465 outPose->ikdata = NULL;
466 outPose->ikparam = MEM_dupallocN(src->ikparam);
468 for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
469 // TODO: rename this argument...
471 copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
472 pchan->constraints= listb;
473 pchan->path= NULL; // XXX remove this line when the new motionpaths are ready... (depreceated code)
474 pchan->mpath= NULL; /* motion paths should not get copied yet... */
478 pchan->prop= IDP_CopyProperty(pchan->prop);
482 /* for now, duplicate Bone Groups too when doing this */
484 BLI_duplicatelist(&outPose->agroups, &src->agroups);
489 void init_pose_itasc(bItasc *itasc)
492 itasc->iksolver = IKSOLVER_ITASC;
493 itasc->minstep = 0.01f;
494 itasc->maxstep = 0.06f;
495 itasc->numiter = 100;
497 itasc->precision = 0.005f;
498 itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION;
499 itasc->feedback = 20.f;
500 itasc->maxvel = 50.f;
501 itasc->solver = ITASC_SOLVER_SDLS;
502 itasc->dampmax = 0.5;
503 itasc->dampeps = 0.15;
506 void init_pose_ikparam(bPose *pose)
509 switch (pose->iksolver) {
511 itasc = MEM_callocN(sizeof(bItasc), "itasc");
512 init_pose_itasc(itasc);
513 pose->ikparam = itasc;
515 case IKSOLVER_LEGACY:
517 pose->ikparam = NULL;
522 void free_pose_channel(bPoseChannel *pchan)
524 // XXX this case here will need to be removed when the new motionpaths are ready
526 MEM_freeN(pchan->path);
531 animviz_free_motionpath(pchan->mpath);
535 free_constraints(&pchan->constraints);
538 IDP_FreeProperty(pchan->prop);
539 MEM_freeN(pchan->prop);
543 void free_pose_channels(bPose *pose)
547 if (pose->chanbase.first) {
548 for (pchan = pose->chanbase.first; pchan; pchan=pchan->next)
549 free_pose_channel(pchan);
551 BLI_freelistN(&pose->chanbase);
555 void free_pose(bPose *pose)
558 /* free pose-channels */
559 free_pose_channels(pose);
561 /* free pose-groups */
562 if (pose->agroups.first)
563 BLI_freelistN(&pose->agroups);
565 /* free IK solver state */
566 BIK_clear_data(pose);
568 /* free IK solver param */
570 MEM_freeN(pose->ikparam);
577 static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
579 bConstraint *pcon, *con;
581 VECCOPY(pchan->loc, chan->loc);
582 VECCOPY(pchan->size, chan->size);
583 VECCOPY(pchan->eul, chan->eul);
584 VECCOPY(pchan->rotAxis, chan->rotAxis);
585 pchan->rotAngle= chan->rotAngle;
586 QUATCOPY(pchan->quat, chan->quat);
587 pchan->rotmode= chan->rotmode;
588 copy_m4_m4(pchan->chan_mat, (float(*)[4])chan->chan_mat);
589 copy_m4_m4(pchan->pose_mat, (float(*)[4])chan->pose_mat);
590 pchan->flag= chan->flag;
592 con= chan->constraints.first;
593 for(pcon= pchan->constraints.first; pcon && con; pcon= pcon->next, con= con->next) {
594 pcon->enforce= con->enforce;
595 pcon->headtail= con->headtail;
599 /* makes copies of internal data, unlike copy_pose_channel_data which only
600 * copies the pose state.
601 * hint: use when copying bones in editmode (on returned value from verify_pose_channel) */
602 void duplicate_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *pchan_from)
604 /* copy transform locks */
605 pchan->protectflag = pchan_from->protectflag;
607 /* copy rotation mode */
608 pchan->rotmode = pchan_from->rotmode;
610 /* copy bone group */
611 pchan->agrp_index= pchan_from->agrp_index;
613 /* ik (dof) settings */
614 pchan->ikflag = pchan_from->ikflag;
615 VECCOPY(pchan->limitmin, pchan_from->limitmin);
616 VECCOPY(pchan->limitmax, pchan_from->limitmax);
617 VECCOPY(pchan->stiffness, pchan_from->stiffness);
618 pchan->ikstretch= pchan_from->ikstretch;
619 pchan->ikrotweight= pchan_from->ikrotweight;
620 pchan->iklinweight= pchan_from->iklinweight;
623 copy_constraints(&pchan->constraints, &pchan_from->constraints);
627 /* unlikely but possible it exists */
628 IDP_FreeProperty(pchan->prop);
629 MEM_freeN(pchan->prop);
632 if(pchan_from->prop) {
633 pchan->prop= IDP_CopyProperty(pchan_from->prop);
637 pchan->custom= pchan_from->custom;
641 /* checks for IK constraint, Spline IK, and also for Follow-Path constraint.
642 * can do more constraints flags later
644 /* pose should be entirely OK */
645 void update_pose_constraint_flags(bPose *pose)
647 bPoseChannel *pchan, *parchan;
651 for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
654 pose->flag &= ~POSE_CONSTRAINTS_TIMEDEPEND;
657 for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
658 for (con= pchan->constraints.first; con; con= con->next) {
659 if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
660 bKinematicConstraint *data = (bKinematicConstraint*)con->data;
662 pchan->constflag |= PCHAN_HAS_IK;
664 if(data->tar==NULL || (data->tar->type==OB_ARMATURE && data->subtarget[0]==0))
665 pchan->constflag |= PCHAN_HAS_TARGET;
667 /* negative rootbone = recalc rootbone index. used in do_versions */
668 if(data->rootbone<0) {
671 if(data->flag & CONSTRAINT_IK_TIP) parchan= pchan;
672 else parchan= pchan->parent;
676 if((parchan->bone->flag & BONE_CONNECTED)==0)
678 parchan= parchan->parent;
682 else if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) {
683 bFollowPathConstraint *data= (bFollowPathConstraint *)con->data;
685 /* for drawing constraint colors when color set allows this */
686 pchan->constflag |= PCHAN_HAS_CONST;
688 /* if we have a valid target, make sure that this will get updated on frame-change
689 * (needed for when there is no anim-data for this pose)
691 if ((data->tar) && (data->tar->type==OB_CURVE))
692 pose->flag |= POSE_CONSTRAINTS_TIMEDEPEND;
694 else if (con->type == CONSTRAINT_TYPE_SPLINEIK)
695 pchan->constflag |= PCHAN_HAS_SPLINEIK;
697 pchan->constflag |= PCHAN_HAS_CONST;
702 /* Clears all BONE_UNKEYED flags for every pose channel in every pose
703 * This should only be called on frame changing, when it is acceptable to
704 * do this. Otherwise, these flags should not get cleared as poses may get lost.
706 void framechange_poses_clear_unkeyed(void)
712 /* This needs to be done for each object that has a pose */
713 // TODO: proxies may/may not be correctly handled here... (this needs checking)
714 for (ob= G.main->object.first; ob; ob= ob->id.next) {
715 /* we only need to do this on objects with a pose */
716 if ( (pose= ob->pose) ) {
717 for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
719 pchan->bone->flag &= ~BONE_UNKEYED;
725 /* ************************** Bone Groups ************************** */
727 /* Adds a new bone-group */
728 void pose_add_group (Object *ob)
730 bPose *pose= (ob) ? ob->pose : NULL;
733 if (ELEM(NULL, ob, ob->pose))
736 grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
737 strcpy(grp->name, "Group");
738 BLI_addtail(&pose->agroups, grp);
739 BLI_uniquename(&pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), sizeof(grp->name));
741 pose->active_group= BLI_countlist(&pose->agroups);
744 /* Remove the active bone-group */
745 void pose_remove_group (Object *ob)
747 bPose *pose= (ob) ? ob->pose : NULL;
748 bActionGroup *grp = NULL;
752 if (ELEM(NULL, ob, pose))
754 if (pose->active_group <= 0)
757 /* get group to remove */
758 grp= BLI_findlink(&pose->agroups, pose->active_group-1);
760 /* adjust group references (the trouble of using indices!):
761 * - firstly, make sure nothing references it
762 * - also, make sure that those after this item get corrected
764 for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
765 if (pchan->agrp_index == pose->active_group)
766 pchan->agrp_index= 0;
767 else if (pchan->agrp_index > pose->active_group)
771 /* now, remove it from the pose */
772 BLI_freelinkN(&pose->agroups, grp);
773 pose->active_group= 0;
777 /* ************** F-Curve Utilities for Actions ****************** */
779 /* Check if the given action has any keyframes */
780 short action_has_motion(const bAction *act)
784 /* return on the first F-Curve that has some keyframes/samples defined */
786 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
796 /* Calculate the extents of given action */
797 void calc_action_range(const bAction *act, float *start, float *end, short incl_modifiers)
800 float min=999999999.0f, max=-999999999.0f;
801 short foundvert=0, foundmod=0;
804 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
805 /* if curve has keyframes, consider them first */
809 /* get extents for this curve */
810 calc_fcurve_range(fcu, &nmin, &nmax);
812 /* compare to the running tally */
813 min= MIN2(min, nmin);
814 max= MAX2(max, nmax);
819 /* if incl_modifiers is enabled, need to consider modifiers too
820 * - only really care about the last modifier
822 if ((incl_modifiers) && (fcu->modifiers.last)) {
823 FModifier *fcm= fcu->modifiers.last;
825 /* only use the maximum sensible limits of the modifiers if they are more extreme */
827 case FMODIFIER_TYPE_LIMITS: /* Limits F-Modifier */
829 FMod_Limits *fmd= (FMod_Limits *)fcm->data;
831 if (fmd->flag & FCM_LIMIT_XMIN) {
832 min= MIN2(min, fmd->rect.xmin);
834 if (fmd->flag & FCM_LIMIT_XMAX) {
835 max= MAX2(max, fmd->rect.xmax);
840 case FMODIFIER_TYPE_CYCLES: /* Cycles F-Modifier */
842 FMod_Cycles *fmd= (FMod_Cycles *)fcm->data;
844 if (fmd->before_mode != FCM_EXTRAPOLATE_NONE)
846 if (fmd->after_mode != FCM_EXTRAPOLATE_NONE)
851 // TODO: function modifier may need some special limits
853 default: /* all other standard modifiers are on the infinite range... */
864 if (foundvert || foundmod) {
865 if(min==max) max+= 1.0f;
875 /* Return flags indicating which transforms the given object/posechannel has
876 * - if 'curves' is provided, a list of links to these curves are also returned
878 short action_get_item_transforms (bAction *act, Object *ob, bPoseChannel *pchan, ListBase *curves)
885 /* build PointerRNA from provided data to obtain the paths to use */
887 RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr);
889 RNA_id_pointer_create((ID *)ob, &ptr);
893 /* get the basic path to the properties of interest */
894 basePath= RNA_path_from_ID_to_struct(&ptr);
895 if (basePath == NULL)
898 /* search F-Curves for the given properties
899 * - we cannot use the groups, since they may not be grouped in that way...
901 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
902 char *bPtr=NULL, *pPtr=NULL;
904 /* if enough flags have been found, we can stop checking unless we're also getting the curves */
905 if ((flags == ACT_TRANS_ALL) && (curves == NULL))
908 /* just in case... */
909 if (fcu->rna_path == NULL)
912 /* step 1: check for matching base path */
913 bPtr= strstr(fcu->rna_path, basePath);
916 /* step 2: check for some property with transforms
917 * - to speed things up, only check for the ones not yet found
918 * unless we're getting the curves too
919 * - if we're getting the curves, the BLI_genericNodeN() creates a LinkData
920 * node wrapping the F-Curve, which then gets added to the list
921 * - once a match has been found, the curve cannot possibly be any other one
923 if ((curves) || (flags & ACT_TRANS_LOC) == 0) {
924 pPtr= strstr(fcu->rna_path, "location");
925 if ((pPtr) && (pPtr >= bPtr)) {
926 flags |= ACT_TRANS_LOC;
929 BLI_addtail(curves, BLI_genericNodeN(fcu));
934 if ((curves) || (flags & ACT_TRANS_SCALE) == 0) {
935 pPtr= strstr(fcu->rna_path, "scale");
936 if ((pPtr) && (pPtr >= bPtr)) {
937 flags |= ACT_TRANS_SCALE;
940 BLI_addtail(curves, BLI_genericNodeN(fcu));
945 if ((curves) || (flags & ACT_TRANS_ROT) == 0) {
946 pPtr= strstr(fcu->rna_path, "rotation");
947 if ((pPtr) && (pPtr >= bPtr)) {
948 flags |= ACT_TRANS_ROT;
951 BLI_addtail(curves, BLI_genericNodeN(fcu));
961 /* return flags found */
965 /* ************** Pose Management Tools ****************** */
967 /* Copy the data from the action-pose (src) into the pose */
968 /* both args are assumed to be valid */
969 /* exported to game engine */
970 /* Note! this assumes both poses are aligned, this isnt always true when dealing with user poses */
971 void extract_pose_from_pose(bPose *pose, const bPose *src)
973 const bPoseChannel *schan;
974 bPoseChannel *pchan= pose->chanbase.first;
977 printf("extract_pose_from_pose source and target are the same\n");
981 for (schan=src->chanbase.first; (schan && pchan); schan=schan->next, pchan= pchan->next) {
982 copy_pose_channel_data(pchan, schan);
986 /* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */
987 void rest_pose(bPose *pose)
995 memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
996 memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
998 for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
999 for (i=0; i<3; i++) {
1000 pchan->loc[i]= 0.0f;
1001 pchan->quat[i+1]= 0.0f;
1002 pchan->eul[i]= 0.0f;
1003 pchan->size[i]= 1.0f;
1004 pchan->rotAxis[i]= 0.0f;
1006 pchan->quat[0]= pchan->rotAxis[1]= 1.0f;
1007 pchan->rotAngle= 0.0f;
1009 pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
1013 /* both poses should be in sync */
1014 void copy_pose_result(bPose *to, bPose *from)
1016 bPoseChannel *pchanto, *pchanfrom;
1018 if(to==NULL || from==NULL) {
1019 printf("pose result copy error to:%p from:%p\n", to, from); // debug temp
1024 printf("copy_pose_result source and target are the same\n");
1029 for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) {
1030 pchanto= get_pose_channel(to, pchanfrom->name);
1032 copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat);
1033 copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat);
1035 /* used for local constraints */
1036 VECCOPY(pchanto->loc, pchanfrom->loc);
1037 QUATCOPY(pchanto->quat, pchanfrom->quat);
1038 VECCOPY(pchanto->eul, pchanfrom->eul);
1039 VECCOPY(pchanto->size, pchanfrom->size);
1041 VECCOPY(pchanto->pose_head, pchanfrom->pose_head);
1042 VECCOPY(pchanto->pose_tail, pchanfrom->pose_tail);
1044 pchanto->rotmode= pchanfrom->rotmode;
1045 pchanto->flag= pchanfrom->flag;
1046 pchanto->protectflag= pchanfrom->protectflag;
1051 /* For the calculation of the effects of an Action at the given frame on an object
1052 * This is currently only used for the Action Constraint
1054 void what_does_obaction (Scene *scene, Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
1056 bActionGroup *agrp= action_groups_find_named(act, groupname);
1059 clear_workob(workob);
1062 copy_m4_m4(workob->obmat, ob->obmat);
1063 copy_m4_m4(workob->parentinv, ob->parentinv);
1064 copy_m4_m4(workob->constinv, ob->constinv);
1065 workob->parent= ob->parent;
1066 workob->track= ob->track;
1068 workob->rotmode= ob->rotmode;
1070 workob->trackflag= ob->trackflag;
1071 workob->upflag= ob->upflag;
1073 workob->partype= ob->partype;
1074 workob->par1= ob->par1;
1075 workob->par2= ob->par2;
1076 workob->par3= ob->par3;
1078 workob->constraints.first = ob->constraints.first;
1079 workob->constraints.last = ob->constraints.last;
1081 workob->pose= pose; /* need to set pose too, since this is used for both types of Action Constraint */
1083 strcpy(workob->parsubstr, ob->parsubstr);
1084 strcpy(workob->id.name, "OB<ConstrWorkOb>"); /* we don't use real object name, otherwise RNA screws with the real thing */
1086 /* if we're given a group to use, it's likely to be more efficient (though a bit more dangerous) */
1088 /* specifically evaluate this group only */
1091 /* get RNA-pointer for the workob's ID */
1092 RNA_id_pointer_create(&workob->id, &id_ptr);
1094 /* execute action for this group only */
1095 animsys_evaluate_action_group(&id_ptr, act, agrp, NULL, cframe);
1100 /* init animdata, and attach to workob */
1101 memset(&adt, 0, sizeof(AnimData));
1104 adt.recalc= ADT_RECALC_ANIM;
1107 /* execute effects of Action on to workob (or it's PoseChannels) */
1108 BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM);
1112 /* ********** NLA with non-poses works with ipo channels ********** */
1114 #if 0 // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)
1116 /* ************************ Blending with NLA *************** */
1118 static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mode)
1123 case ACTSTRIPMODE_BLEND:
1124 dstweight = 1.0F - srcweight;
1126 case ACTSTRIPMODE_ADD:
1133 interp_v3_v3v3(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight);
1139 bone matching diagram, strips A and B
1141 .------------------------.
1143 '------------------------'
1145 . .-------------v----------.
1147 . '------------------------'
1150 offset: . 0 . A-B . A-b2+B
1156 static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src, float srcweight, short mode)
1158 /* matching offset bones */
1159 /* take dst offset, and put src on on that location */
1161 if(strip->offs_bone[0]==0)
1164 /* are we also blending with matching bones? */
1165 if(strip->prev && strip->start>=strip->prev->start) {
1166 bPoseChannel *dpchan= get_pose_channel(dst, strip->offs_bone);
1168 bPoseChannel *spchan= get_pose_channel(src, strip->offs_bone);
1172 /* dst->ctime has the internal strip->prev action time */
1173 /* map this time to nla time */
1175 float ctime= get_actionstrip_frame(strip, src->ctime, 1);
1177 if( ctime > strip->prev->end) {
1178 bActionChannel *achan;
1180 /* add src to dest, minus the position of src on strip->prev->end */
1182 ctime= get_actionstrip_frame(strip, strip->prev->end, 0);
1184 achan= get_action_channel(strip->act, strip->offs_bone);
1185 if(achan && achan->ipo) {
1187 /* Evaluates and sets the internal ipo value */
1188 calc_ipo(achan->ipo, ctime);
1189 /* This call also sets the pchan flags */
1190 execute_action_ipo(achan, &pchan);
1192 /* store offset that moves src to location of pchan */
1193 sub_v3_v3v3(vec, dpchan->loc, pchan.loc);
1195 mul_mat3_m4_v3(dpchan->bone->arm_mat, vec);
1199 /* store offset that moves src to location of dst */
1201 sub_v3_v3v3(vec, dpchan->loc, spchan->loc);
1202 mul_mat3_m4_v3(dpchan->bone->arm_mat, vec);
1205 /* if blending, we only add with factor scrweight */
1206 mul_v3_fl(vec, srcweight);
1208 add_v3_v3v3(dst->cyclic_offset, dst->cyclic_offset, vec);
1213 add_v3_v3v3(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset);
1216 /* added "sizecorr" here, to allow armatures to be scaled and still have striding.
1217 Only works for uniform scaling. In general I'd advise against scaling armatures ever though! (ton)
1219 static float stridechannel_frame(Object *ob, float sizecorr, bActionStrip *strip, Path *path, float pathdist, float *stride_offset)
1221 bAction *act= strip->act;
1222 const char *name= strip->stridechannel;
1223 bActionChannel *achan= get_action_channel(act, name);
1224 int stride_axis= strip->stride_axis;
1226 if(achan && achan->ipo) {
1227 IpoCurve *icu= NULL;
1228 float minx=0.0f, maxx=0.0f, miny=0.0f, maxy=0.0f;
1231 if(stride_axis==0) stride_axis= AC_LOC_X;
1232 else if(stride_axis==1) stride_axis= AC_LOC_Y;
1233 else stride_axis= AC_LOC_Z;
1235 /* calculate the min/max */
1236 for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
1237 if(icu->adrcode==stride_axis) {
1238 if(icu->totvert>1) {
1240 minx= icu->bezt[0].vec[1][0];
1241 maxx= icu->bezt[icu->totvert-1].vec[1][0];
1243 miny= icu->bezt[0].vec[1][1];
1244 maxy= icu->bezt[icu->totvert-1].vec[1][1];
1250 if(foundvert && miny!=maxy) {
1251 float stridelen= sizecorr*fabs(maxy-miny), striptime;
1252 float actiondist, pdist, pdistNewNormalized, offs;
1253 float vec1[4], vec2[4], dir[3];
1255 /* internal cycling, actoffs is in frames */
1256 offs= stridelen*strip->actoffs/(maxx-minx);
1258 /* amount path moves object */
1259 pdist = (float)fmod (pathdist+offs, stridelen);
1260 striptime= pdist/stridelen;
1262 /* amount stride bone moves */
1263 actiondist= sizecorr*eval_icu(icu, minx + striptime*(maxx-minx)) - miny;
1265 pdist = fabs(actiondist) - pdist;
1266 pdistNewNormalized = (pathdist+pdist)/path->totdist;
1268 /* now we need to go pdist further (or less) on cu path */
1269 where_on_path(ob, (pathdist)/path->totdist, vec1, dir); /* vec needs size 4 */
1270 if (pdistNewNormalized <= 1) {
1271 // search for correction in positive path-direction
1272 where_on_path(ob, pdistNewNormalized, vec2, dir); /* vec needs size 4 */
1273 sub_v3_v3v3(stride_offset, vec2, vec1);
1276 // we reached the end of the path, search backwards instead
1277 where_on_path(ob, (pathdist-pdist)/path->totdist, vec2, dir); /* vec needs size 4 */
1278 sub_v3_v3v3(stride_offset, vec1, vec2);
1280 mul_mat3_m4_v3(ob->obmat, stride_offset);
1287 static void cyclic_offs_bone(Object *ob, bPose *pose, bActionStrip *strip, float time)
1289 /* only called when strip has cyclic, so >= 1.0f works... */
1291 bActionChannel *achan= get_action_channel(strip->act, strip->offs_bone);
1293 if(achan && achan->ipo) {
1294 IpoCurve *icu= NULL;
1296 float min[3]={0.0f, 0.0f, 0.0f}, max[3]={0.0f, 0.0f, 0.0f};
1297 int index=0, foundvert= 0;
1299 /* calculate the min/max */
1300 for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
1301 if(icu->totvert>1) {
1303 if(icu->adrcode==AC_LOC_X)
1305 else if(icu->adrcode==AC_LOC_Y)
1307 else if(icu->adrcode==AC_LOC_Z)
1313 min[index]= icu->bezt[0].vec[1][1];
1314 max[index]= icu->bezt[icu->totvert-1].vec[1][1];
1318 /* bring it into armature space */
1319 sub_v3_v3v3(min, max, min);
1320 bone= get_named_bone(ob->data, strip->offs_bone); /* weak */
1322 mul_mat3_m4_v3(bone->arm_mat, min);
1324 /* dominant motion, cyclic_offset was cleared in rest_pose */
1325 if (strip->flag & (ACTSTRIP_CYCLIC_USEX | ACTSTRIP_CYCLIC_USEY | ACTSTRIP_CYCLIC_USEZ)) {
1326 if (strip->flag & ACTSTRIP_CYCLIC_USEX) pose->cyclic_offset[0]= time*min[0];
1327 if (strip->flag & ACTSTRIP_CYCLIC_USEY) pose->cyclic_offset[1]= time*min[1];
1328 if (strip->flag & ACTSTRIP_CYCLIC_USEZ) pose->cyclic_offset[2]= time*min[2];
1330 if( fabs(min[0]) >= fabs(min[1]) && fabs(min[0]) >= fabs(min[2]))
1331 pose->cyclic_offset[0]= time*min[0];
1332 else if( fabs(min[1]) >= fabs(min[0]) && fabs(min[1]) >= fabs(min[2]))
1333 pose->cyclic_offset[1]= time*min[1];
1335 pose->cyclic_offset[2]= time*min[2];
1343 /* simple case for now; only the curve path with constraint value > 0.5 */
1344 /* blending we might do later... */
1345 static Object *get_parent_path(Object *ob)
1349 if(ob->parent && ob->parent->type==OB_CURVE)
1352 for (con = ob->constraints.first; con; con=con->next) {
1353 if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) {
1354 if(con->enforce>0.5f) {
1355 bFollowPathConstraint *data= con->data;
1363 /* ************** do the action ************ */
1365 /* ----- nla, etc. --------- */
1367 static void do_nla(Scene *scene, Object *ob, int blocktype)
1371 ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL};
1372 bActionStrip *strip, *striplast=NULL, *stripfirst=NULL;
1373 float striptime, frametime, length, actlength;
1374 float blendfac, stripframe;
1375 float scene_cfra= frame_to_float(scene, scene->r.cfra);
1378 if(blocktype==ID_AR) {
1379 copy_pose(&tpose, ob->pose, 1);
1380 rest_pose(ob->pose); // potentially destroying current not-keyed pose
1383 key= ob_get_key(ob);
1386 /* check on extend to left or right, when no strip is hit by 'cfra' */
1387 for (strip=ob->nlastrips.first; strip; strip=strip->next) {
1388 /* escape loop on a hit */
1389 if( scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f) /* note 0.1 comes back below */
1391 if(scene_cfra < strip->start) {
1392 if(stripfirst==NULL)
1394 else if(stripfirst->start > strip->start)
1397 else if(scene_cfra > strip->end) {
1400 else if(striplast->end < strip->end)
1404 if(strip==NULL) { /* extend */
1406 scene_cfra= striplast->end;
1408 scene_cfra= stripfirst->start;
1411 /* and now go over all strips */
1412 for (strip=ob->nlastrips.first; strip; strip=strip->next){
1415 if (strip->act && !(strip->flag & ACTSTRIP_MUTE)) { /* so theres an action */
1417 /* Determine if the current frame is within the strip's range */
1418 length = strip->end-strip->start;
1419 actlength = strip->actend-strip->actstart;
1420 striptime = (scene_cfra-(strip->start)) / length;
1421 stripframe = (scene_cfra-(strip->start)) ;
1423 if (striptime>=0.0){
1425 if(blocktype==ID_AR)
1428 /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
1429 if (striptime < 1.0f + 0.1f/length) {
1432 if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype==ID_AR) && (ob->ipoflag & OB_DISABLE_PATH)==0){
1433 Object *parent= get_parent_path(ob);
1436 Curve *cu = parent->data;
1439 if (cu->flag & CU_PATH){
1440 /* Ensure we have a valid path */
1441 if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(scene, parent, 0);
1444 /* Find the position on the path */
1445 ctime= bsystem_time(scene, ob, scene_cfra, 0.0);
1447 if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
1448 /* correct for actions not starting on zero */
1449 ctime= (ctime - strip->actstart)/cu->pathlen;
1450 CLAMP(ctime, 0.0, 1.0);
1452 pdist = ctime*cu->path->totdist;
1454 if(tpose && strip->stridechannel[0]) {
1455 striptime= stridechannel_frame(parent, ob->size[0], strip, cu->path, pdist, tpose->stride_offset);
1458 if (strip->stridelen) {
1459 striptime = pdist / strip->stridelen;
1460 striptime = (float)fmod (striptime+strip->actoffs, 1.0);
1466 frametime = (striptime * actlength) + strip->actstart;
1467 frametime= bsystem_time(scene, ob, frametime, 0.0);
1469 if(blocktype==ID_AR) {
1470 extract_pose_from_action (tpose, strip->act, frametime);
1472 else if(blocktype==ID_OB) {
1473 extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
1475 extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
1482 /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
1486 if(strip->repeat!=1.0f) {
1487 float cycle= striptime*strip->repeat;
1489 striptime = (float)fmod (cycle, 1.0f + 0.1f/length);
1492 if(blocktype==ID_AR)
1493 cyclic_offs_bone(ob, tpose, strip, cycle);
1496 frametime = (striptime * actlength) + strip->actstart;
1497 frametime= nla_time(scene, frametime, (float)strip->repeat);
1499 if(blocktype==ID_AR) {
1500 extract_pose_from_action (tpose, strip->act, frametime);
1502 else if(blocktype==ID_OB) {
1503 extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
1505 extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
1513 if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
1514 /* we want the strip to hold on the exact fraction of the repeat value */
1516 frametime = actlength * (strip->repeat-(int)strip->repeat);
1517 if(frametime<=0.000001f) frametime= actlength; /* rounding errors... */
1518 frametime= bsystem_time(scene, ob, frametime+strip->actstart, 0.0);
1520 if(blocktype==ID_AR)
1521 extract_pose_from_action (tpose, strip->act, frametime);
1522 else if(blocktype==ID_OB) {
1523 extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
1525 extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
1528 /* handle cycle hold */
1529 if(strip->repeat!=1.0f) {
1530 if(blocktype==ID_AR)
1531 cyclic_offs_bone(ob, tpose, strip, strip->repeat-1.0f);
1538 /* Handle blendin & blendout */
1540 /* Handle blendin */
1542 if (strip->blendin>0.0 && stripframe<=strip->blendin && scene_cfra>=strip->start){
1543 blendfac = stripframe/strip->blendin;
1545 else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && scene_cfra<=strip->end){
1546 blendfac = (length-stripframe)/(strip->blendout);
1551 if(blocktype==ID_AR) {/* Blend this pose with the accumulated pose */
1552 /* offset bone, for matching cycles */
1553 blend_pose_offset_bone (strip, ob->pose, tpose, blendfac, strip->mode);
1555 blend_poses (ob->pose, tpose, blendfac, strip->mode);
1557 blend_pose_strides (ob->pose, tpose, blendfac, strip->mode);
1560 blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode);
1561 BLI_freelistN(&tchanbase);
1568 if(blocktype==ID_OB) {
1569 execute_ipochannels(&chanbase);
1571 else if(blocktype==ID_AR) {
1572 /* apply stride offset to object */
1573 add_v3_v3v3(ob->obmat[3], ob->obmat[3], ob->pose->stride_offset);
1580 BLI_freelistN(&chanbase);
1583 #endif // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)