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:
authorTon Roosendaal <ton@blender.org>2005-10-10 22:05:30 +0400
committerTon Roosendaal <ton@blender.org>2005-10-10 22:05:30 +0400
commit4bd9775936c1b5a1656713d8c6a679b711b93d93 (patch)
tree7a4d0c39ffef76f3f34f5dea7ad85a02587414a1 /source/blender/blenkernel
parent9b8868532a9e0970f83eb68ef36144eaca9525a1 (diff)
Stupid me! Committed in wrong console with wrong dir... here's the rest of
all files for the Ipo/Action/NLA makeover...
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_action.h22
-rw-r--r--source/blender/blenkernel/BKE_constraint.h9
-rw-r--r--source/blender/blenkernel/BKE_ipo.h13
-rw-r--r--source/blender/blenkernel/bad_level_call_stubs/stubs.c5
-rw-r--r--source/blender/blenkernel/intern/action.c477
-rw-r--r--source/blender/blenkernel/intern/constraint.c20
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c8
-rw-r--r--source/blender/blenkernel/intern/effect.c4
-rw-r--r--source/blender/blenkernel/intern/ipo.c231
-rw-r--r--source/blender/blenkernel/intern/object.c5
10 files changed, 537 insertions, 257 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 5b8c8c1a929..21e7b2f7fc0 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -75,8 +75,13 @@ void free_action(struct bAction * id);
void make_local_action(struct bAction *act);
-/* if NULL it does all, otherwise only from Object */
-void do_all_actions(struct Object *);
+/* only for armatures, doing pose actions only too */
+void do_all_pose_actions(struct Object *);
+/* only for objects, doing only 1 channel */
+void do_all_object_actions(struct Object *);
+/* only for Mesh, Curve, Surface, Lattice, doing only Shape channel */
+void do_all_shape_actions(struct Object *);
+
/**
* Return a pointer to the pose channel of the given name
@@ -121,13 +126,20 @@ void extract_pose_from_action(struct bPose *pose, struct bAction *act,
* and return the channel with the given name.
* Returns NULL if no channel.
*/
-struct bActionChannel *get_named_actionchannel(struct bAction *act,
- const char *name);
+struct bActionChannel *get_action_channel(struct bAction *act, const char *name);
+/**
+ * Iterate through the action channels of the action
+ * and return the channel with the given name.
+ * Returns and adds new channel if no channel.
+ */
+struct bActionChannel *verify_action_channel(struct bAction *act, const char *name);
-// exported for game engine
+/* exported for game engine */
void blend_poses(struct bPose *dst, const struct bPose *src, float srcweight, short mode);
void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
+/* map global time (frame nr) to strip converted time, doesn't clip */
+float get_action_frame(struct Object *ob, float cframe);
#ifdef __cplusplus
};
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index fc45daf455f..2bec643d5b0 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -51,13 +51,14 @@ void clone_constraint_channels (struct ListBase *dst, struct ListBase *src);
void relink_constraints (struct ListBase *list);
void free_constraint_data (struct bConstraint *con);
-void do_constraint_channels (struct ListBase *conbase, struct ListBase *chanbase, float ctime);
-short get_constraint_target_matrix (struct bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float size[3], float time);
-struct bConstraintChannel *find_constraint_channel (ListBase *list, const char *name);
+/* channels */
+struct bConstraintChannel *get_constraint_channel (ListBase *list, const char *name);
+struct bConstraintChannel *verify_constraint_channel (ListBase *list, const char *name);
void free_constraint_channels (ListBase *chanbase);
/* Gemeric functions */
-
+void do_constraint_channels (struct ListBase *conbase, struct ListBase *chanbase, float ctime);
+short get_constraint_target_matrix (struct bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float size[3], float time);
char constraint_has_target (struct bConstraint *con);
struct Object *get_constraint_target(struct bConstraint *con, char **subtarget);
void set_constraint_target(struct bConstraint *con, struct Object *ob, char *subtarget);
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index 6acbceb8e3f..a1fb24ae9b2 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -49,13 +49,15 @@ struct Sequence;
struct ListBase;
struct BezTriple;
struct ID;
-/* struct IPO_Channel; */
+struct bPoseChannel;
+struct bActionChannel;
+struct rctf;
float frame_to_float(int cfra);
void free_ipo_curve(struct IpoCurve *icu);
void free_ipo(struct Ipo *ipo);
-
+void ipo_default_v2d_cur(int blocktype, struct rctf *cur);
struct Ipo *add_ipo(char *name, int idcode);
struct Ipo *copy_ipo(struct Ipo *ipo);
void make_local_obipo(struct Ipo *ipo);
@@ -79,9 +81,14 @@ void calc_ipo(struct Ipo *ipo, float ctime);
void write_ipo_poin(void *poin, int type, float val);
float read_ipo_poin(void *poin, int type);
void *give_mtex_poin(struct MTex *mtex, int adrcode );
+
void *get_ipo_poin(struct ID *id, struct IpoCurve *icu, int *type);
+void *get_pchan_ipo_poin(struct bPoseChannel *pchan, int adrcode);
+
void set_icu_vars(struct IpoCurve *icu);
+
void execute_ipo(struct ID *id, struct Ipo *ipo);
+void execute_action_ipo(struct bActionChannel *achan, struct bPoseChannel *pchan);
void do_ipo_nocalc(struct Ipo *ipo);
void do_ipo(struct Ipo *ipo);
@@ -96,9 +103,9 @@ int calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime);
void clear_delta_obipo(struct Ipo *ipo);
void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt);
void make_cfra_list(struct Ipo *ipo, struct ListBase *elems);
+
/* the sort is an IPO_Channel... */
int IPO_GetChannels(struct Ipo *ipo, short *channels);
-void test_ipo_get(void);
float IPO_GetFloatValue(struct Ipo *ipo,
/* struct IPO_Channel channel, */
diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
index f5d06fc5a7e..706c9980344 100644
--- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c
+++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
@@ -61,11 +61,6 @@ char* getIpoCurveName( struct IpoCurve * icu )
return 0;
};
-struct IpoCurve *get_ipocurve(struct ID *from, short type, int adrcode, struct Ipo *useipo)
-{
- return 0;
-}
-
void insert_vert_ipo(struct IpoCurve *icu, float x, float y)
{
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 2df93f47e2a..276f5ecdcec 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -310,7 +310,10 @@ void update_pose_constraint_flags(bPose *pose)
/* ************************ END Pose channels *************** */
-bActionChannel *get_named_actionchannel(bAction *act, const char *name)
+/* ************************ Action channels *************** */
+
+
+bActionChannel *get_action_channel(bAction *act, const char *name)
{
bActionChannel *chan;
@@ -325,6 +328,22 @@ bActionChannel *get_named_actionchannel(bAction *act, const char *name)
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) {
+ if (!chan) {
+ chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
+ strcpy (chan->name, name);
+ BLI_addtail (&act->chanbase, chan);
+ }
+ }
+ return chan;
+}
+
/* ************************ Blending with NLA *************** */
@@ -395,20 +414,25 @@ float calc_action_start(const bAction *act)
if (!act)
return 0;
- for (chan=act->chanbase.first; chan; chan=chan->next){
- for (icu=chan->ipo->curve.first; icu; icu=icu->next)
- for (i=0; i<icu->totvert; i++){
- size = MIN2 (size, icu->bezt[i].vec[1][0]);
- foundvert=1;
-
+ for (chan=act->chanbase.first; chan; chan=chan->next) {
+ if(chan->ipo) {
+ for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
+ for (i=0; i<icu->totvert; i++){
+ size = MIN2 (size, icu->bezt[i].vec[1][0]);
+ foundvert=1;
+ }
}
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
- for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
+ }
+ for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
+ if(conchan->ipo) {
+ for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
for (i=0; i<icu->totvert; i++){
size = MIN2 (size, icu->bezt[i].vec[1][0]);
foundvert=1;
}
+ }
}
+ }
}
if (!foundvert)
@@ -428,16 +452,20 @@ float calc_action_end(const bAction *act)
if (!act)
return 0;
- for (chan=act->chanbase.first; chan; chan=chan->next){
- for (icu=chan->ipo->curve.first; icu; icu=icu->next)
- for (i=0; i<icu->totvert; i++)
- size = MAX2 (size, icu->bezt[i].vec[1][0]);
-
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
+ for (chan=act->chanbase.first; chan; chan=chan->next) {
+ if(chan->ipo) {
+ for (icu=chan->ipo->curve.first; icu; icu=icu->next)
+ for (i=0; i<icu->totvert; i++)
+ size = MAX2 (size, icu->bezt[i].vec[1][0]);
+ }
+
+ for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
+ if(conchan->ipo) {
for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
for (i=0; i<icu->totvert; i++)
size = MAX2 (size, icu->bezt[i].vec[1][0]);
}
+ }
}
return size;
}
@@ -469,18 +497,16 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
/* Copy the data from the action into the pose */
for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
- achan= get_named_actionchannel(act, pchan->name);
+ achan= get_action_channel(act, pchan->name);
pchan->flag= 0;
if(achan) {
ipo = achan->ipo;
if (ipo) {
- act->achan= achan; // for ipos
- act->pchan= pchan; // for ipos
/* Evaluates and sets the internal ipo value */
calc_ipo(ipo, ctime);
/* This call also sets the pchan flags */
- execute_ipo((ID*)act, achan->ipo);
+ execute_action_ipo(achan, pchan);
do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
}
@@ -488,8 +514,8 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
}
}
-/* for do_all_actions, clears the pose */
-static void rest_pose(bPose *pose, int clearflag)
+/* for do_all_pose_actions, clears the pose */
+static void rest_pose(bPose *pose)
{
bPoseChannel *chan;
int i;
@@ -505,13 +531,166 @@ static void rest_pose(bPose *pose, int clearflag)
}
chan->quat[0]=1.0;
- if (clearflag)
- chan->flag =0;
+ chan->flag =0;
+ }
+}
+
+/* ********** NLA with non-poses works with ipo channels ********** */
+
+typedef struct NlaIpoChannel {
+ struct NlaIpoChannel *next, *prev;
+ float val;
+ void *poin;
+ int type;
+} NlaIpoChannel;
+
+static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime)
+{
+ bActionChannel *achan= get_action_channel(act, name);
+ IpoCurve *icu;
+ NlaIpoChannel *nic;
+
+ if(achan==NULL) return;
+
+ if(achan->ipo) {
+ calc_ipo(achan->ipo, ctime);
+
+ for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
+
+ nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel");
+ BLI_addtail(lb, nic);
+ nic->val= icu->curval;
+ nic->poin= get_ipo_poin(id, icu, &nic->type);
+ }
+ }
+
+ /* constraint channels only for objects */
+ if(GS(id->name)==ID_OB) {
+ Object *ob= (Object *)id;
+ bConstraint *con;
+ bConstraintChannel *conchan;
+
+ for (con=ob->constraints.first; con; con=con->next) {
+ conchan = get_constraint_channel(&achan->constraintChannels, con->name);
+
+ if(conchan && conchan->ipo) {
+ calc_ipo(conchan->ipo, ctime);
+
+ icu= conchan->ipo->curve.first; // only one ipo now
+ if(icu) {
+ nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel constr");
+ BLI_addtail(lb, nic);
+ nic->val= icu->curval;
+ nic->poin= &con->enforce;
+ nic->type= IPO_FLOAT;
+ }
+ }
+ }
+ }
+}
+
+static NlaIpoChannel *find_nla_ipochannel(ListBase *lb, void *poin)
+{
+ NlaIpoChannel *nic;
+
+ if(poin) {
+ for(nic= lb->first; nic; nic= nic->next) {
+ if(nic->poin==poin)
+ return nic;
+ }
+ }
+ return NULL;
+}
+
+
+static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int mode)
+{
+ NlaIpoChannel *snic, *dnic, *next;
+ float dstweight;
+
+ switch (mode){
+ case POSE_BLEND:
+ dstweight = 1.0F - srcweight;
+ break;
+ case POSE_ADD:
+ dstweight = 1.0F;
+ break;
+ default :
+ dstweight = 1.0F;
+ }
+
+ for(snic= src->first; snic; snic= next) {
+ next= snic->next;
+
+ dnic= find_nla_ipochannel(dst, snic->poin);
+ if(dnic==NULL) {
+ /* remove from src list, and insert in dest */
+ BLI_remlink(src, snic);
+ BLI_addtail(dst, snic);
+ }
+ else {
+ /* we do the blend */
+ dnic->val= dstweight*dnic->val + srcweight*snic->val;
+ }
+ }
+}
+
+static void execute_ipochannels(Object *ob, ListBase *lb)
+{
+ NlaIpoChannel *nic;
+
+ for(nic= lb->first; nic; nic= nic->next) {
+ if(nic->poin) write_ipo_poin(nic->poin, nic->type, nic->val);
}
}
+
/* ************** time ****************** */
+static bActionStrip *get_active_strip(Object *ob)
+{
+ 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;
+ return NULL;
+}
+
+/* non clipped mapping of strip */
+static float get_actionstrip_frame(bActionStrip *strip, float cframe)
+{
+ float length, actlength, repeat;
+
+ if (strip->flag & ACTSTRIP_USESTRIDE)
+ repeat= 1.0f;
+ else
+ repeat= strip->repeat;
+
+ length = strip->end-strip->start;
+ if(length==0.0f)
+ length= 1.0f;
+ actlength = strip->actend-strip->actstart;
+
+ return repeat*actlength*(cframe - strip->start)/length + strip->actstart;
+}
+
+/* if the conditions match, it converts current time to strip time */
+float get_action_frame(Object *ob, float cframe)
+{
+ bActionStrip *strip= get_active_strip(ob);
+
+ if(strip)
+ return get_actionstrip_frame(strip, cframe);
+ return cframe;
+}
+
/* this now only used for repeating cycles, to enable fields and blur. */
/* the whole time control in blender needs serious thinking... */
static float nla_time(float cfra, float unit)
@@ -538,129 +717,185 @@ static float nla_time(float cfra, float unit)
/* ************** do the action ************ */
-void do_all_actions(Object *ob)
+static void do_nla(Object *ob, int blocktype)
{
- bPose *tpose=NULL;
+ bPose *tpose= NULL;
+ ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL};
bActionStrip *strip;
- float ctime, striptime, frametime, length, actlength;
+ float striptime, frametime, length, actlength;
float blendfac, stripframe;
int doit;
-
- // only to have safe calls from editor
- if(ob==NULL) return;
- if(ob->type!=OB_ARMATURE || ob->pose==NULL) return;
-
- ctime= bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0);
-
- if(ob->pose->flag & POSE_LOCKED) { // no actions to execute while transform
- ;
- }
- else if(ob->action) {
- /* Do local action (always overrides the nla actions) */
- extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0));
+ if(blocktype==ID_AR) {
+ copy_pose(&tpose, ob->pose, 1);
+ rest_pose(ob->pose); // potentially destroying current not-keyed pose
}
- else if(ob->nlastrips.first) {
+
+ for (strip=ob->nlastrips.first; strip; strip=strip->next){
doit=0;
-
- copy_pose(&tpose, ob->pose, 1);
- rest_pose(ob->pose, 1); // potentially destroying current not-keyed pose
-
- for (strip=ob->nlastrips.first; strip; strip=strip->next){
- doit = 0;
- if (strip->act){
- /* Determine if the current frame is within the strip's range */
- length = strip->end-strip->start;
- actlength = strip->actend-strip->actstart;
- striptime = (G.scene->r.cfra-(strip->start)) / length;
- stripframe = (G.scene->r.cfra-(strip->start)) ;
-
-
- if (striptime>=0.0){
-
- rest_pose(tpose, 1);
-
- /* Handle path */
- if (strip->flag & ACTSTRIP_USESTRIDE){
- if (ob->parent && ob->parent->type==OB_CURVE){
- Curve *cu = ob->parent->data;
- float ctime, pdist;
-
- if (cu->flag & CU_PATH){
- /* Ensure we have a valid path */
- if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(ob->parent, 0);
- if(cu->path) {
-
- /* Find the position on the path */
- ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
-
- if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
- ctime /= cu->pathlen;
- CLAMP(ctime, 0.0, 1.0);
- }
- pdist = ctime*cu->path->totdist;
-
- if (strip->stridelen)
- striptime = pdist / strip->stridelen;
- else
- striptime = 0;
-
- striptime = (float)fmod (striptime, 1.0);
-
- frametime = (striptime * actlength) + strip->actstart;
- extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
- doit=1;
+ if (strip->act){ /* so theres an action */
+
+ /* Determine if the current frame is within the strip's range */
+ length = strip->end-strip->start;
+ actlength = strip->actend-strip->actstart;
+ striptime = (G.scene->r.cfra-(strip->start)) / length;
+ stripframe = (G.scene->r.cfra-(strip->start)) ;
+
+ if (striptime>=0.0){
+
+ if(blocktype==ID_AR)
+ rest_pose(tpose);
+
+ /* Handle path */
+ if (strip->flag & ACTSTRIP_USESTRIDE){
+ if (ob->parent && ob->parent->type==OB_CURVE){
+ Curve *cu = ob->parent->data;
+ float ctime, pdist;
+
+ if (cu->flag & CU_PATH){
+ /* Ensure we have a valid path */
+ if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(ob->parent, 0);
+ if(cu->path) {
+
+ /* Find the position on the path */
+ ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
+
+ if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
+ ctime /= cu->pathlen;
+ CLAMP(ctime, 0.0, 1.0);
}
+ pdist = ctime*cu->path->totdist;
+
+ if (strip->stridelen)
+ striptime = pdist / strip->stridelen;
+ else
+ striptime = 0;
+
+ striptime = (float)fmod (striptime, 1.0);
+
+ frametime = (striptime * actlength) + strip->actstart;
+
+ if(blocktype==ID_AR)
+ extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ else if(blocktype==ID_OB)
+ extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", bsystem_time(ob, 0, frametime, 0.0));
+
+ doit=1;
}
}
}
-
- /* Handle repeat */
-
- else if (striptime < 1.0){
- /* Mod to repeat */
- striptime*=strip->repeat;
- striptime = (float)fmod (striptime, 1.0);
+ }
+ /* Handle repeat */
+ else if (striptime < 1.0) {
+ /* Mod to repeat */
+ striptime*=strip->repeat;
+ striptime = (float)fmod (striptime, 1.0);
+
+ frametime = (striptime * actlength) + strip->actstart;
+
+ if(blocktype==ID_AR)
+ extract_pose_from_action (tpose, strip->act, nla_time(frametime, (float)strip->repeat));
+ else if(blocktype==ID_OB)
+ extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", nla_time(frametime, (float)strip->repeat));
+ doit=1;
+ }
+ /* Handle extend */
+ else{
+ if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
+ striptime = 1.0;
frametime = (striptime * actlength) + strip->actstart;
- extract_pose_from_action (tpose, strip->act, nla_time(frametime, (float)strip->repeat));
+
+ if(blocktype==ID_AR)
+ extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
+ else if(blocktype==ID_OB)
+ extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", bsystem_time(ob, 0, frametime, 0.0));
+
doit=1;
}
- /* Handle extend */
- else{
- if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
- striptime = 1.0;
- frametime = (striptime * actlength) + strip->actstart;
- extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
- doit=1;
- }
+ }
+
+ /* Handle blendin & blendout */
+ if (doit){
+ /* Handle blendin */
+
+ if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
+ blendfac = stripframe/strip->blendin;
}
-
- /* Handle blendin & blendout */
- if (doit){
- /* Handle blendin */
-
- if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){
- blendfac = stripframe/strip->blendin;
- }
- else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
- blendfac = (length-stripframe)/(strip->blendout);
- }
- else
- blendfac = 1;
-
- /* Blend this pose with the accumulated pose */
+ else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){
+ blendfac = (length-stripframe)/(strip->blendout);
+ }
+ else
+ blendfac = 1;
+
+ if(blocktype==ID_AR) /* Blend this pose with the accumulated pose */
blend_poses (ob->pose, tpose, blendfac, strip->mode);
+ else {
+ blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode);
+ BLI_freelistN(&tchanbase);
}
- }
- }
+ }
+ }
}
}
+ if(blocktype==ID_OB) {
+ execute_ipochannels(ob, &chanbase);
+ }
+
if (tpose){
free_pose_channels(tpose);
MEM_freeN(tpose);
}
+ if(chanbase.first)
+ BLI_freelistN(&chanbase);
+
+
+}
+
+void do_all_pose_actions(Object *ob)
+{
+
+ // only to have safe calls from editor
+ if(ob==NULL) return;
+ if(ob->type!=OB_ARMATURE || ob->pose==NULL) return;
+
+ if(ob->pose->flag & POSE_LOCKED) { // no actions to execute while transform
+ ;
+ }
+ else if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
+ float cframe= (float) G.scene->r.cfra;
+
+ cframe= get_action_frame(ob, cframe);
+
+ extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, cframe, 0.0));
+ }
+ else if(ob->nlastrips.first) {
+ do_nla(ob, ID_AR);
+ }
+}
+
+/* called from where_is_object */
+void do_all_object_actions(Object *ob)
+{
+ if(ob==NULL) return;
+
+ /* Do local action */
+ if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
+ ListBase tchanbase= {NULL, NULL};
+ float cframe= (float) G.scene->r.cfra;
+
+ cframe= get_action_frame(ob, cframe);
+
+ extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(ob, 0, cframe, 0.0));
+ if(tchanbase.first) {
+ execute_ipochannels(ob, &tchanbase);
+ BLI_freelistN(&tchanbase);
+ }
+ }
+ else if(ob->nlastrips.first) {
+ do_nla(ob, ID_OB);
+ }
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 6fd3cbcfd8b..48d9db1a516 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -618,7 +618,7 @@ void *new_constraint_data (short type)
return result;
}
-bConstraintChannel *find_constraint_channel (ListBase *list, const char *name)
+bConstraintChannel *get_constraint_channel (ListBase *list, const char *name)
{
bConstraintChannel *chan;
@@ -630,6 +630,22 @@ bConstraintChannel *find_constraint_channel (ListBase *list, const char *name)
return NULL;
}
+/* finds or creates new constraint channel */
+bConstraintChannel *verify_constraint_channel (ListBase *list, const char *name)
+{
+ bConstraintChannel *chan;
+
+ chan= get_constraint_channel (list, name);
+ if(chan==NULL) {
+ chan= MEM_callocN(sizeof(bConstraintChannel), "new constraint chan");
+ BLI_addtail(list, chan);
+ strcpy(chan->name, name);
+ }
+
+ return chan;
+}
+
+
/* ***************** Evaluating ********************* */
/* does ipos only */
@@ -640,7 +656,7 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime)
IpoCurve *icu=NULL;
for (con=conbase->first; con; con=con->next) {
- chan = find_constraint_channel(chanbase, con->name);
+ chan = get_constraint_channel(chanbase, con->name);
if (chan && chan->ipo){
calc_ipo(chan->ipo, ctime);
for (icu=chan->ipo->curve.first; icu; icu=icu->next){
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 68ab67c399d..76acb9cfdc8 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1460,8 +1460,12 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay)
if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB;
}
- if(ob->action) ob->recalc |= OB_RECALC_DATA;
- else if(ob->nlastrips.first) ob->recalc |= OB_RECALC_DATA;
+ if(ob->action || ob->nlastrips.first) {
+ /* since actions now are mixed, we set the recalcs on the safe side */
+ ob->recalc |= OB_RECALC_OB;
+ if(ob->type==OB_ARMATURE)
+ ob->recalc |= OB_RECALC_DATA;
+ }
else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
else {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 86ac9d76db5..b604af0f221 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -1235,7 +1235,7 @@ void build_particle_system(Object *ob)
par->ctime= -1234567.0;
do_ob_key(par);
if(par->type==OB_ARMATURE) {
- do_all_actions(par); // only does this object actions
+ do_all_pose_actions(par); // only does this object actions
where_is_pose(par);
}
par= par->parent;
@@ -1318,7 +1318,7 @@ void build_particle_system(Object *ob)
do_ob_key(par);
if(par->type==OB_ARMATURE) {
- do_all_actions(par); // only does this object actions
+ do_all_pose_actions(par); // only does this object actions
where_is_pose(par);
}
par= par->parent;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 7c8a272c372..c6c99137761 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -205,13 +205,56 @@ void free_ipo(Ipo *ipo)
}
}
+/* on adding new ipos, or for empty views */
+void ipo_default_v2d_cur(int blocktype, rctf *cur)
+{
+ if(blocktype==ID_CA) {
+ cur->xmin= G.scene->r.sfra;
+ cur->xmax= G.scene->r.efra;
+ cur->ymin= 0.0;
+ cur->ymax= 100.0;
+ }
+ else if ELEM5(blocktype, ID_MA, ID_CU, ID_WO, ID_LA, ID_CO) {
+ cur->xmin= (float)G.scene->r.sfra-0.1;
+ cur->xmax= G.scene->r.efra;
+ cur->ymin= (float)-0.1;
+ cur->ymax= (float)+1.1;
+ }
+ else if(blocktype==ID_TE) {
+ cur->xmin= (float)G.scene->r.sfra-0.1;
+ cur->xmax= G.scene->r.efra;
+ cur->ymin= (float)-0.1;
+ cur->ymax= (float)+1.1;
+ }
+ else if(blocktype==ID_SEQ) {
+ cur->xmin= -5.0+G.scene->r.sfra;
+ cur->xmax= 105.0;
+ cur->ymin= (float)-0.1;
+ cur->ymax= (float)+1.1;
+ }
+ else if(blocktype==ID_KE) {
+ cur->xmin= (float)G.scene->r.sfra-0.1;
+ cur->xmax= G.scene->r.efra;
+ cur->ymin= (float)-0.1;
+ cur->ymax= (float)+2.1;
+ }
+ else { /* ID_OB and everything else */
+ cur->xmin= G.scene->r.sfra;
+ cur->xmax= G.scene->r.efra;
+ cur->ymin= -5.0;
+ cur->ymax= +5.0;
+ }
+}
+
+
Ipo *add_ipo(char *name, int idcode)
{
Ipo *ipo;
ipo= alloc_libblock(&G.main->ipo, ID_IP, name);
ipo->blocktype= idcode;
-
+ ipo_default_v2d_cur(idcode, &ipo->cur);
+
return ipo;
}
@@ -226,11 +269,9 @@ Ipo *copy_ipo(Ipo *ipo)
duplicatelist(&(ipon->curve), &(ipo->curve));
- icu= ipon->curve.first;
- while(icu) {
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
icu->bezt= MEM_dupallocN(icu->bezt);
if(icu->driver) icu->driver= MEM_dupallocN(icu->driver);
- icu= icu->next;
}
return ipon;
@@ -389,10 +430,9 @@ void make_local_ipo(Ipo *ipo)
IpoCurve *find_ipocurve(Ipo *ipo, int adrcode)
{
if(ipo) {
- IpoCurve *icu= ipo->curve.first;
- while(icu) {
+ IpoCurve *icu;
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
if(icu->adrcode==adrcode) return icu;
- icu= icu->next;
}
}
return NULL;
@@ -909,12 +949,9 @@ void calc_ipo(Ipo *ipo, float ctime)
if(ipo==NULL) return;
- icu= ipo->curve.first;
- while(icu) {
-
- if(icu->driver || (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime);
-
- icu= icu->next;
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver || (icu->flag & IPO_LOCK)==0)
+ calc_icu(icu, ctime);
}
}
@@ -1090,14 +1127,11 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
Lamp *la;
Sequence *seq;
World *wo;
- bAction *act;
- bActionChannel *achan;
- bPoseChannel *pchan;
*type= IPO_FLOAT;
if( GS(id->name)==ID_OB) {
-
+
ob= (Object *)id;
switch(icu->adrcode) {
@@ -1172,56 +1206,6 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
break;
}
}
- else if (GS(id->name)==ID_AC){
- act= (bAction *)id;
- achan = act->achan;
- pchan = act->pchan;
- if (!pchan || !achan)
- return NULL;
- switch (icu->adrcode){
- case AC_QUAT_W:
- poin= &(pchan->quat[0]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_QUAT_X:
- poin= &(pchan->quat[1]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_QUAT_Y:
- poin= &(pchan->quat[2]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_QUAT_Z:
- poin= &(pchan->quat[3]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_LOC_X:
- poin= &(pchan->loc[0]);
- pchan->flag |= POSE_LOC;
- break;
- case AC_LOC_Y:
- poin= &(pchan->loc[1]);
- pchan->flag |= POSE_LOC;
- break;
- case AC_LOC_Z:
- poin= &(pchan->loc[2]);
- pchan->flag |= POSE_LOC;
- break;
- case AC_SIZE_X:
- poin= &(pchan->size[0]);
- pchan->flag |= POSE_SIZE;
- break;
- case AC_SIZE_Y:
- poin= &(pchan->size[1]);
- pchan->flag |= POSE_SIZE;
- break;
- case AC_SIZE_Z:
- poin= &(pchan->size[2]);
- pchan->flag |= POSE_SIZE;
- break;
- };
- }
-
else if( GS(id->name)==ID_MA) {
ma= (Material *)id;
@@ -1738,7 +1722,7 @@ void set_icu_vars(IpoCurve *icu)
}
}
-
+/* not for actions or constraints! */
void execute_ipo(ID *id, Ipo *ipo)
{
IpoCurve *icu;
@@ -1747,11 +1731,70 @@ void execute_ipo(ID *id, Ipo *ipo)
if(ipo==NULL) return;
- icu= ipo->curve.first;
- while(icu) {
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
poin= get_ipo_poin(id, icu, &type);
if(poin) write_ipo_poin(poin, type, icu->curval);
- icu= icu->next;
+ }
+}
+
+void *get_pchan_ipo_poin(bPoseChannel *pchan, int adrcode)
+{
+ void *poin= NULL;
+
+ switch (adrcode) {
+ case AC_QUAT_W:
+ poin= &(pchan->quat[0]);
+ pchan->flag |= POSE_ROT;
+ break;
+ case AC_QUAT_X:
+ poin= &(pchan->quat[1]);
+ pchan->flag |= POSE_ROT;
+ break;
+ case AC_QUAT_Y:
+ poin= &(pchan->quat[2]);
+ pchan->flag |= POSE_ROT;
+ break;
+ case AC_QUAT_Z:
+ poin= &(pchan->quat[3]);
+ pchan->flag |= POSE_ROT;
+ break;
+ case AC_LOC_X:
+ poin= &(pchan->loc[0]);
+ pchan->flag |= POSE_LOC;
+ break;
+ case AC_LOC_Y:
+ poin= &(pchan->loc[1]);
+ pchan->flag |= POSE_LOC;
+ break;
+ case AC_LOC_Z:
+ poin= &(pchan->loc[2]);
+ pchan->flag |= POSE_LOC;
+ break;
+ case AC_SIZE_X:
+ poin= &(pchan->size[0]);
+ pchan->flag |= POSE_SIZE;
+ break;
+ case AC_SIZE_Y:
+ poin= &(pchan->size[1]);
+ pchan->flag |= POSE_SIZE;
+ break;
+ case AC_SIZE_Z:
+ poin= &(pchan->size[2]);
+ pchan->flag |= POSE_SIZE;
+ break;
+ }
+ return poin;
+}
+
+void execute_action_ipo(bActionChannel *achan, bPoseChannel *pchan)
+{
+
+ if(achan && achan->ipo) {
+ IpoCurve *icu;
+ for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
+ void *poin= get_pchan_ipo_poin(pchan, icu->adrcode);
+ if(poin) write_ipo_poin(poin, IPO_FLOAT, icu->curval);
+ }
}
}
@@ -1925,12 +1968,8 @@ int has_ipo_code(Ipo *ipo, int code)
if(ipo==NULL) return 0;
- icu= ipo->curve.first;
- while(icu) {
-
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
if(icu->adrcode==code) return 1;
-
- icu= icu->next;
}
return 0;
}
@@ -2036,8 +2075,7 @@ int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime)
if(ipo==NULL) return 0;
- icu= ipo->curve.first;
- while(icu) {
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
if(icu->adrcode == adrcode) {
if(icu->flag & IPO_LOCK);
else calc_icu(icu, *ctime);
@@ -2045,7 +2083,6 @@ int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime)
*ctime= icu->curval;
return 1;
}
- icu= icu->next;
}
return 0;
@@ -2108,8 +2145,7 @@ void make_cfra_list(Ipo *ipo, ListBase *elems)
int a;
if(ipo->blocktype==ID_OB) {
- icu= ipo->curve.first;
- while(icu) {
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
if(icu->flag & IPO_VISIBLE) {
switch(icu->adrcode) {
case OB_DLOC_X:
@@ -2147,12 +2183,10 @@ void make_cfra_list(Ipo *ipo, ListBase *elems)
break;
}
}
- icu= icu->next;
}
}
else if(ipo->blocktype==ID_AC) {
- icu= ipo->curve.first;
- while(icu) {
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
if(icu->flag & IPO_VISIBLE) {
switch(icu->adrcode) {
case AC_LOC_X:
@@ -2176,7 +2210,6 @@ void make_cfra_list(Ipo *ipo, ListBase *elems)
break;
}
}
- icu= icu->next;
}
}
else {
@@ -2216,14 +2249,10 @@ int IPO_GetChannels(Ipo *ipo, IPO_Channel *channels)
if(ipo==NULL) return 0;
- icu= ipo->curve.first;
- while(icu) {
-
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
channels[total]= icu->adrcode;
total++;
if(total>31) break;
-
- icu= icu->next;
}
return total;
@@ -2245,25 +2274,3 @@ float IPO_GetFloatValue(Ipo *ipo, IPO_Channel channel, float ctime)
return ctime;
}
-
-
-void test_ipo_get()
-{
- Object *ob;
- int tot;
- IPO_Channel chan[32];
-
- ob = (G.scene->basact ? G.scene->basact->object : 0);
-
- if(ob==NULL) return;
- if(ob->ipo==NULL) return;
-
- tot= IPO_GetChannels(ob->ipo, chan);
- printf("tot %d \n", tot);
-
- while(tot--) {
- printf("var1 %d \n", chan[tot]);
- }
-
- printf("var1 %f \n", IPO_GetFloatValue(ob->ipo, chan[0], 10.0));
-}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index aa8efe61565..6bdf6a7faa5 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1306,6 +1306,9 @@ void where_is_object_time(Object *ob, float ctime)
calc_ipo(ob->ipo, stime);
execute_ipo((ID *)ob, ob->ipo);
}
+ else
+ do_all_object_actions(ob);
+
/* do constraint ipos ... */
do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime);
}
@@ -1796,7 +1799,7 @@ void object_handle_update(Object *ob)
/* this actually only happens for reading old files... */
if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
armature_rebuild_pose(ob, ob->data);
- do_all_actions(ob);
+ do_all_pose_actions(ob);
where_is_pose(ob);
}
}