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:
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r--source/blender/blenkernel/intern/action.c510
1 files changed, 206 insertions, 304 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 06597c983ca..d468daef52a 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -35,11 +35,11 @@
#include "MEM_guardedalloc.h"
+#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
@@ -52,7 +52,7 @@
#include "BKE_constraint.h"
#include "BKE_displist.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
+#include "BKE_fcurve.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -81,63 +81,34 @@
/* ***************** Library data level operations on action ************** */
-bAction *add_empty_action(const char name[])
+nAction *add_empty_action(const char name[])
{
- bAction *act;
+ nAction *act;
act= alloc_libblock(&G.main->action, ID_AC, name);
- act->id.flag |= LIB_FAKEUSER;
+ act->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
act->id.us++;
return act;
}
-static void make_local_action_channels(bAction *act)
-{
- bActionChannel *chan;
- bConstraintChannel *conchan;
-
- for (chan=act->chanbase.first; chan; chan=chan->next) {
- if(chan->ipo) {
- if(chan->ipo->id.us==1) {
- chan->ipo->id.lib= NULL;
- chan->ipo->id.flag= LIB_LOCAL;
- new_id(0, (ID *)chan->ipo, 0);
- }
- else {
- chan->ipo= copy_ipo(chan->ipo);
- }
- }
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
- if(conchan->ipo) {
- if(conchan->ipo->id.us==1) {
- conchan->ipo->id.lib= NULL;
- conchan->ipo->id.flag= LIB_LOCAL;
- new_id(0, (ID *)conchan->ipo, 0);
- }
- else {
- conchan->ipo= copy_ipo(conchan->ipo);
- }
- }
- }
- }
-}
-
-void make_local_action(bAction *act)
+// does copy_fcurve...
+void make_local_action(nAction *act)
{
Object *ob;
- bAction *actn;
+ nAction *actn;
int local=0, lib=0;
- if(act->id.lib==0) return;
- if(act->id.us==1) {
+ if (act->id.lib==0) return;
+ if (act->id.us==1) {
act->id.lib= 0;
act->id.flag= LIB_LOCAL;
- make_local_action_channels(act);
+ //make_local_action_channels(act);
new_id(0, (ID *)act, 0);
return;
}
+#if 0 // XXX old animation system
ob= G.main->object.first;
while(ob) {
if(ob->action==act) {
@@ -146,17 +117,19 @@ void make_local_action(bAction *act)
}
ob= ob->id.next;
}
+#endif
if(local && lib==0) {
act->id.lib= 0;
act->id.flag= LIB_LOCAL;
- make_local_action_channels(act);
+ //make_local_action_channels(act);
new_id(0, (ID *)act, 0);
}
else if(local && lib) {
actn= copy_action(act);
actn->id.us= 0;
+#if 0 // XXX old animation system
ob= G.main->object.first;
while(ob) {
if(ob->action==act) {
@@ -169,24 +142,25 @@ void make_local_action(bAction *act)
}
ob= ob->id.next;
}
+#endif // XXX old animation system
}
}
-void free_action (bAction *act)
+void free_action (nAction *act)
{
- bActionChannel *chan;
+ FCurve *fcu, *fcn;
+
+ /* sanity check */
+ if (act == NULL)
+ return;
- /* Free channels */
- for (chan=act->chanbase.first; chan; chan=chan->next) {
- if (chan->ipo)
- chan->ipo->id.us--;
- free_constraint_channels(&chan->constraintChannels);
+ /* Free F-Curves */
+ for (fcu= act->curves.first; fcu; fcu= fcn) {
+ fcn= fcu->next;
+ free_fcurve(fcu);
}
- if (act->chanbase.first)
- BLI_freelistN(&act->chanbase);
-
/* Free groups */
if (act->groups.first)
BLI_freelistN(&act->groups);
@@ -196,10 +170,10 @@ void free_action (bAction *act)
BLI_freelistN(&act->markers);
}
-bAction *copy_action (bAction *src)
+nAction *copy_action (nAction *src)
{
- bAction *dst = NULL;
- bActionChannel *dchan, *schan;
+ nAction *dst = NULL;
+ //bActionChannel *dchan, *schan;
bActionGroup *dgrp, *sgrp;
if (!src) return NULL;
@@ -210,6 +184,7 @@ bAction *copy_action (bAction *src)
BLI_duplicatelist(&(dst->groups), &(src->groups));
BLI_duplicatelist(&(dst->markers), &(src->markers));
+#if 0 // XXX old animation system
for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next) {
for (dgrp=dst->groups.first, sgrp=src->groups.first; dgrp && sgrp; dgrp=dgrp->next, sgrp=sgrp->next) {
if (dchan->grp == sgrp) {
@@ -227,8 +202,9 @@ bAction *copy_action (bAction *src)
dchan->ipo = copy_ipo(dchan->ipo);
copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels);
}
+#endif // XXX old animation system
- dst->id.flag |= LIB_FAKEUSER;
+ dst->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
dst->id.us++;
return dst;
@@ -284,7 +260,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
Mat4One(chan->constinv);
- BLI_addtail (&pose->chanbase, chan);
+ BLI_addtail(&pose->chanbase, chan);
return chan;
}
@@ -528,53 +504,24 @@ void framechange_poses_clear_unkeyed(void)
/* ************************ END Pose channels *************** */
-/* ************************ Action channels *************** */
-
-
-bActionChannel *get_action_channel(bAction *act, const char *name)
-{
- bActionChannel *chan;
-
- if (!act || !name)
- return NULL;
-
- for (chan = act->chanbase.first; chan; chan=chan->next) {
- if (!strcmp (chan->name, name))
- return chan;
- }
-
- return NULL;
-}
-
-/* returns existing channel, or adds new one. In latter case it doesnt activate it, context is required for that */
-bActionChannel *verify_action_channel(bAction *act, const char *name)
-{
- bActionChannel *chan;
-
- chan= get_action_channel(act, name);
- if (chan == NULL) {
- chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
- strncpy(chan->name, name, 31);
- BLI_addtail(&act->chanbase, chan);
- }
- return chan;
-}
-
/* ************** time ****************** */
static bActionStrip *get_active_strip(Object *ob)
{
+#if 0 // XXX old animation system
bActionStrip *strip;
if(ob->action==NULL)
return NULL;
-
+
for (strip=ob->nlastrips.first; strip; strip=strip->next)
if(strip->flag & ACTSTRIP_ACTIVE)
break;
if(strip && strip->act==ob->action)
return strip;
+#endif // XXX old animation system
+
return NULL;
}
@@ -621,6 +568,174 @@ float get_action_frame_inv(Object *ob, float cframe)
}
+
+
+/* Calculate the extents of given action */
+void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
+{
+ FCurve *fcu;
+ float min=999999999.0f, max=-999999999.0f;
+ int foundvert=0;
+
+ if (act) {
+#if 0 // XXX old animation system
+ for (chan=act->chanbase.first; chan; chan=chan->next) {
+ if ((incl_hidden) || (chan->flag & ACHAN_HIDDEN)==0) {
+ if (chan->ipo) {
+ for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
+ if (icu->totvert) {
+ min= MIN2(min, icu->bezt[0].vec[1][0]);
+ max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
+ foundvert=1;
+ }
+ }
+ }
+ for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (conchan->ipo) {
+ for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
+ if (icu->totvert) {
+ min= MIN2(min, icu->bezt[0].vec[1][0]);
+ max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
+ foundvert=1;
+ }
+ }
+ }
+ }
+ }
+ }
+#endif // XXX old animation system
+ }
+ if (foundvert) {
+ if(min==max) max+= 1.0f;
+ *start= min;
+ *end= max;
+ }
+ else {
+ *start= 0.0f;
+ *end= 1.0f;
+ }
+}
+
+/* Copy the data from the action-pose (src) into the pose */
+/* both args are assumed to be valid */
+/* exported to game engine */
+void extract_pose_from_pose(bPose *pose, const bPose *src)
+{
+ const bPoseChannel *schan;
+ bPoseChannel *pchan= pose->chanbase.first;
+
+ if (pose==src) {
+ printf("extract_pose_from_pose source and target are the same\n");
+ return;
+ }
+
+ for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) {
+ copy_pose_channel_data(pchan, schan);
+ }
+}
+
+/* Pose should exist, can have any number of channels too (used for constraint) */
+void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
+{
+#if 0 // XXX old animation system
+ bActionChannel *achan;
+ bPoseChannel *pchan;
+ Ipo *ipo;
+
+ if (!act)
+ return;
+ if (!pose)
+ return;
+
+ /* Copy the data from the action into the pose */
+ for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
+ /* skip this pose channel if it has been tagged as having unkeyed poses */
+ if ((pchan->bone) && (pchan->bone->flag & BONE_UNKEYED))
+ continue;
+
+ /* get action channel and clear pchan-transform flags */
+ achan= get_action_channel(act, pchan->name);
+ pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
+
+ if (achan) {
+ ipo = achan->ipo;
+ if (ipo) {
+ /* Evaluates and sets the internal ipo value */
+ calc_ipo(ipo, ctime);
+ /* This call also sets the pchan flags */
+ execute_action_ipo(achan, pchan);
+ }
+ /* 0 = do all ipos, not only drivers */
+ do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime, 0);
+ }
+ }
+#endif // XXX old animation system
+
+ pose->ctime= ctime; /* used for cyclic offset matching */
+}
+
+/* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */
+void rest_pose(bPose *pose)
+{
+ bPoseChannel *pchan;
+ int i;
+
+ if (!pose)
+ return;
+
+ memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
+ memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
+
+ for (pchan=pose->chanbase.first; pchan; pchan= pchan->next){
+ for (i=0; i<3; i++) {
+ pchan->loc[i]= 0.0f;
+ pchan->quat[i+1]= 0.0f;
+ pchan->eul[i]= 0.0f;
+ pchan->size[i]= 1.0f;
+ }
+ pchan->quat[0]= 1.0f;
+
+ pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
+ }
+}
+
+/* both poses should be in sync */
+void copy_pose_result(bPose *to, bPose *from)
+{
+ bPoseChannel *pchanto, *pchanfrom;
+
+ if(to==NULL || from==NULL) {
+ printf("pose result copy error\n"); // debug temp
+ return;
+ }
+
+ if (to==from) {
+ printf("copy_pose_result source and target are the same\n");
+ return;
+ }
+
+
+ for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) {
+ pchanto= get_pose_channel(to, pchanfrom->name);
+ if(pchanto) {
+ Mat4CpyMat4(pchanto->pose_mat, pchanfrom->pose_mat);
+ Mat4CpyMat4(pchanto->chan_mat, pchanfrom->chan_mat);
+ /* used for local constraints */
+ VECCOPY(pchanto->loc, pchanfrom->loc);
+ QUATCOPY(pchanto->quat, pchanfrom->quat);
+ VECCOPY(pchanto->size, pchanfrom->size);
+
+ VECCOPY(pchanto->pose_head, pchanfrom->pose_head);
+ VECCOPY(pchanto->pose_tail, pchanfrom->pose_tail);
+ pchanto->flag= pchanfrom->flag;
+ }
+ }
+}
+
+/* ********** NLA with non-poses works with ipo channels ********** */
+
+#if 0 // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)
+
/* ************************ Blending with NLA *************** */
static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mode)
@@ -790,168 +905,6 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
dst->ctime= src->ctime;
}
-/* Calculate the extents of given action */
-void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
-{
- bActionChannel *chan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- float min=999999999.0f, max=-999999999.0f;
- int foundvert=0;
-
- if (act) {
- for (chan=act->chanbase.first; chan; chan=chan->next) {
- if ((incl_hidden) || (chan->flag & ACHAN_HIDDEN)==0) {
- if (chan->ipo) {
- for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
- if (icu->totvert) {
- min= MIN2(min, icu->bezt[0].vec[1][0]);
- max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
- foundvert=1;
- }
- }
- }
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (conchan->ipo) {
- for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
- if (icu->totvert) {
- min= MIN2(min, icu->bezt[0].vec[1][0]);
- max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
- foundvert=1;
- }
- }
- }
- }
- }
- }
- }
- if (foundvert) {
- if(min==max) max+= 1.0f;
- *start= min;
- *end= max;
- }
- else {
- *start= 0.0f;
- *end= 1.0f;
- }
-}
-
-/* Copy the data from the action-pose (src) into the pose */
-/* both args are assumed to be valid */
-/* exported to game engine */
-void extract_pose_from_pose(bPose *pose, const bPose *src)
-{
- const bPoseChannel *schan;
- bPoseChannel *pchan= pose->chanbase.first;
-
- if (pose==src) {
- printf("extract_pose_from_pose source and target are the same\n");
- return;
- }
-
- for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) {
- copy_pose_channel_data(pchan, schan);
- }
-}
-
-/* Pose should exist, can have any number of channels too (used for constraint) */
-void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
-{
- bActionChannel *achan;
- bPoseChannel *pchan;
- Ipo *ipo;
-
- if (!act)
- return;
- if (!pose)
- return;
-
- /* Copy the data from the action into the pose */
- for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
- /* skip this pose channel if it has been tagged as having unkeyed poses */
- if ((pchan->bone) && (pchan->bone->flag & BONE_UNKEYED))
- continue;
-
- /* get action channel and clear pchan-transform flags */
- achan= get_action_channel(act, pchan->name);
- pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
-
- if (achan) {
- ipo = achan->ipo;
- if (ipo) {
- /* Evaluates and sets the internal ipo value */
- calc_ipo(ipo, ctime);
- /* This call also sets the pchan flags */
- execute_action_ipo(achan, pchan);
- }
- /* 0 = do all ipos, not only drivers */
- do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime, 0);
- }
- }
-
- pose->ctime= ctime; /* used for cyclic offset matching */
-}
-
-/* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */
-void rest_pose(bPose *pose)
-{
- bPoseChannel *pchan;
- int i;
-
- if (!pose)
- return;
-
- memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
- memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
-
- for (pchan=pose->chanbase.first; pchan; pchan= pchan->next){
- for (i=0; i<3; i++) {
- pchan->loc[i]= 0.0f;
- pchan->quat[i+1]= 0.0f;
- pchan->eul[i]= 0.0f;
- pchan->size[i]= 1.0f;
- }
- pchan->quat[0]= 1.0f;
-
- pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
- }
-}
-
-/* both poses should be in sync */
-void copy_pose_result(bPose *to, bPose *from)
-{
- bPoseChannel *pchanto, *pchanfrom;
-
- if(to==NULL || from==NULL) {
- printf("pose result copy error\n"); // debug temp
- return;
- }
-
- if (to==from) {
- printf("copy_pose_result source and target are the same\n");
- return;
- }
-
-
- for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) {
- pchanto= get_pose_channel(to, pchanfrom->name);
- if(pchanto) {
- Mat4CpyMat4(pchanto->pose_mat, pchanfrom->pose_mat);
- Mat4CpyMat4(pchanto->chan_mat, pchanfrom->chan_mat);
- /* used for local constraints */
- VECCOPY(pchanto->loc, pchanfrom->loc);
- QUATCOPY(pchanto->quat, pchanfrom->quat);
- VECCOPY(pchanto->size, pchanfrom->size);
-
- VECCOPY(pchanto->pose_head, pchanfrom->pose_head);
- VECCOPY(pchanto->pose_tail, pchanfrom->pose_tail);
- pchanto->flag= pchanfrom->flag;
- }
- }
-}
-
-/* ********** NLA with non-poses works with ipo channels ********** */
-
typedef struct NlaIpoChannel {
struct NlaIpoChannel *next, *prev;
float val;
@@ -1490,55 +1443,4 @@ static void do_nla(Scene *scene, Object *ob, int blocktype)
BLI_freelistN(&chanbase);
}
-void do_all_pose_actions(Scene *scene, Object *ob)
-{
- /* only to have safe calls from editor */
- if(ELEM(NULL, scene, ob)) return;
- if((ob->type!=OB_ARMATURE) || (ob->pose==NULL)) return;
-
- if(ob->pose->flag & POSE_LOCKED) { /* no actions to execute while transform */
- if(ob->pose->flag & POSE_DO_UNLOCK)
- ob->pose->flag &= ~(POSE_LOCKED|POSE_DO_UNLOCK);
- }
- else if( (ob->action) && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || (ob->nlastrips.first==NULL)) ) {
- float cframe= (float) scene->r.cfra;
-
- cframe= get_action_frame(ob, cframe);
-
- extract_pose_from_action(ob->pose, ob->action, bsystem_time(scene, ob, cframe, 0.0));
- }
- else if(ob->nlastrips.first) {
- do_nla(scene, ob, ID_AR);
- }
-
- /* clear POSE_DO_UNLOCK flags that might have slipped through (just in case) */
- ob->pose->flag &= ~POSE_DO_UNLOCK;
-}
-
-/* called from where_is_object */
-void do_all_object_actions(Scene *scene, Object *ob)
-{
- if(ob==NULL) return;
- if(ob->dup_group) return; /* prevent conflicts, might add smarter check later */
-
- /* Do local action */
- if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
- ListBase tchanbase= {NULL, NULL};
- Key *key= ob_get_key(ob);
- float cframe= (float) scene->r.cfra;
-
- cframe= get_action_frame(ob, cframe);
-
- extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(scene, ob, cframe, 0.0));
- if(key)
- extract_ipochannels_from_action(&tchanbase, &key->id, ob->action, "Shape", bsystem_time(scene, ob, cframe, 0.0));
-
- if(tchanbase.first) {
- execute_ipochannels(&tchanbase);
- BLI_freelistN(&tchanbase);
- }
- }
- else if(ob->nlastrips.first) {
- do_nla(scene, ob, ID_OB);
- }
-}
+#endif // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)