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:
authorJoshua Leung <aligorith@gmail.com>2009-01-17 06:12:50 +0300
committerJoshua Leung <aligorith@gmail.com>2009-01-17 06:12:50 +0300
commit44e5b7788bcbe55400bf0d91eed0752ed865b644 (patch)
tree7b69e89ff7f93127d5691f528c5dc9bb85835ee1 /source/blender/blenkernel/intern
parent9bcdb4b758d96d1fe5345858f6c61a90f7c57eac (diff)
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future. Highlights of the new system: * Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action. - F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves. - The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc. * F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated. * Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place) * F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place) * NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still) There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details: http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html So, what currently works: * I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code. * Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock. * Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc. Notes: * Drivers haven't been hooked up yet * Only objects and data directly linked to objects can be animated. * Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change). * Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor) * I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review. In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/action.c510
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c549
-rw-r--r--source/blender/blenkernel/intern/armature.c3
-rw-r--r--source/blender/blenkernel/intern/constraint.c157
-rw-r--r--source/blender/blenkernel/intern/curve.c8
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c29
-rw-r--r--source/blender/blenkernel/intern/fcurve.c1492
-rw-r--r--source/blender/blenkernel/intern/ipo.c5
-rw-r--r--source/blender/blenkernel/intern/key.c74
-rw-r--r--source/blender/blenkernel/intern/lattice.c7
-rw-r--r--source/blender/blenkernel/intern/library.c6
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/object.c112
-rw-r--r--source/blender/blenkernel/intern/particle.c17
-rw-r--r--source/blender/blenkernel/intern/particle_system.c36
-rw-r--r--source/blender/blenkernel/intern/pointcache.c3
-rw-r--r--source/blender/blenkernel/intern/scene.c46
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c16
-rw-r--r--source/blender/blenkernel/intern/sequence.c22
-rw-r--r--source/blender/blenkernel/intern/texture.c11
-rw-r--r--source/blender/blenkernel/intern/world.c6
22 files changed, 2553 insertions, 560 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)
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 6a6d8c46f9e..e9d0fc7c95a 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -368,7 +368,9 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level,
else ok= 0;
}
if(ok) {
+#if 0 // XXX old animation system
do_ob_ipo(scene, ob);
+#endif // XXX old animation system
where_is_object_time(scene, ob, (float)scene->r.cfra);
dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated);
Mat4CpyMat4(dob->omat, copyob.obmat);
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
new file mode 100644
index 00000000000..d377ce044fd
--- /dev/null
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -0,0 +1,549 @@
+/* Testing code for new animation system in 2.5
+ * Copyright 2009, Joshua Leung
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_dynstr.h"
+
+#include "BKE_animsys.h"
+#include "BKE_fcurve.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_types.h"
+
+#include "DNA_anim_types.h"
+
+/* ***************************************** */
+/* AnimData API */
+
+/* Get AnimData from the given ID-block. In order for this to work, we assume that
+ * the AnimData block is stored immediately after the given ID-block in the struct,
+ * as per IdAdtTemplate.
+ */
+AnimData *BKE_animdata_from_id (ID *id)
+{
+ /* sanity check */
+ if (id == NULL)
+ return NULL;
+
+ /* only some ID-blocks have this info for now, so we cast the
+ * types that do to be of type IdAdtTemplate, and extract the
+ * animdata that way
+ */
+ // TODO: finish adding this for the other blocktypes
+ switch (GS(id->name)) {
+ case ID_OB:
+ case ID_KE:
+ case ID_MA: case ID_TE:
+ case ID_LA: case ID_CA: case ID_WO:
+ case ID_SCE:
+ {
+ IdAdtTemplate *iat= (IdAdtTemplate *)id;
+ return &(iat->adt);
+ }
+ break;
+ }
+
+ /* no AnimData (ID-block does not contain this data) */
+ return NULL;
+}
+
+/* Obtain an RNA-Path from the given ID-block to the property of interest
+ * - id: ID block that will be used as the 'root' of the path
+ * - ptr: pointer to struct where setting is stored
+ * - prop: property to get path for
+ */
+// TODO: should this be part of RNA Access API instead? or through editors only?
+char *BKE_animsys_get_rnapath (ID *id, PointerRNA *ptr, PropertyRNA *prop)
+{
+ // FIXME: this could be quite messy to do right :/
+ return NULL;
+}
+
+/* ***************************************** */
+/* Evaluation Data-Setting Backend */
+
+/* Retrieve string to act as RNA-path, adjusted using mapping-table if provided
+ * It returns whether the string needs to be freed (i.e. if it was a temp remapped one)
+ * // FIXME: maybe it would be faster if we didn't have to alloc/free strings like this all the time, but for now it's safer
+ *
+ * - remap: remapping table to use
+ * - path: original path string (as stored in F-Curve data)
+ * - dst: destination string to write data to
+ */
+short animsys_remap_path (AnimMapper *remap, char *path, char **dst)
+{
+ /* is there a valid remapping table to use? */
+ if (remap) {
+ /* find a matching entry... to use to remap */
+ // ...TODO...
+ }
+
+ /* nothing suitable found, so just set dst to look at path (i.e. no alloc/free needed) */
+ *dst= path;
+ return 0;
+}
+
+
+/* Write the given value to a setting using RNA */
+static void animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_index, float value)
+{
+ PropertyRNA *prop;
+ PointerRNA new_ptr;
+
+ /* get property to write to */
+ if (RNA_path_resolve(ptr, path, &new_ptr, &prop))
+ {
+ /* set value - only for animatable numerical values */
+ // FIXME: probably 'editable' might not be enough in future...
+ if (RNA_property_editable(&new_ptr, prop))
+ {
+ switch (RNA_property_type(&new_ptr, prop))
+ {
+ case PROP_BOOLEAN:
+ if (RNA_property_array_length(&new_ptr, prop))
+ RNA_property_boolean_set_array(&new_ptr, prop, array_index, (int)value);
+ else
+ RNA_property_boolean_set(&new_ptr, prop, (int)value);
+ break;
+ case PROP_INT:
+ if (RNA_property_array_length(&new_ptr, prop))
+ RNA_property_int_set_array(&new_ptr, prop, array_index, (int)value);
+ else
+ RNA_property_int_set(&new_ptr, prop, (int)value);
+ break;
+ case PROP_FLOAT:
+ if (RNA_property_array_length(&new_ptr, prop))
+ RNA_property_float_set_array(&new_ptr, prop, array_index, value);
+ else
+ RNA_property_float_set(&new_ptr, prop, value);
+ break;
+ case PROP_ENUM:
+ RNA_property_enum_set(&new_ptr, prop, (int)value);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+/* Simple replacement based data-setting of the FCurve using RNA */
+static void animsys_execute_fcurve (PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
+{
+ char *path = NULL;
+ short free_path=0;
+
+ /* get path, remapped as appropriate to work in its new environment */
+ free_path= animsys_remap_path(remap, fcu->rna_path, &path);
+
+ /* write value to setting */
+ animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval);
+
+ /* free temp path-info */
+ if (free_path)
+ MEM_freeN(path);
+}
+
+/* Evaluate all the F-Curves in the given list
+ * This performs a set of standard checks. If extra checks are required, separate code should be used
+ */
+static void animsys_evaluate_fcurves (PointerRNA *ptr, ListBase *list, AnimMapper *remap, float ctime)
+{
+ FCurve *fcu;
+
+ /* calculate then execute each curve */
+ for (fcu= list->first; fcu; fcu= fcu->next)
+ {
+ /* check if this curve should be skipped */
+ if ((fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED)) == 0)
+ {
+ calculate_fcurve(fcu, ctime);
+ animsys_execute_fcurve(ptr, remap, fcu);
+ }
+ }
+}
+
+/* ***************************************** */
+/* Driver Evaluation */
+
+/* Evaluate Drivers */
+static void animsys_evaluate_drivers (PointerRNA *ptr, AnimData *adt, float ctime)
+{
+ FCurve *fcu;
+
+ /* drivers are stored as F-Curves, but we cannot use the standard code, as we need to check if
+ * the depsgraph requested that this driver be evaluated...
+ */
+ for (fcu= adt->drivers.first; fcu; fcu= fcu->next)
+ {
+ ChannelDriver *driver= fcu->driver;
+
+ /* check if this driver's curve should be skipped */
+ // FIXME: maybe we shouldn't check for muted, though that would make things more confusing, as there's already too many ways to disable?
+ if ((fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED)) == 0)
+ {
+ /* check if driver itself is tagged for recalculation */
+ if ((driver) && (driver->flag & DRIVER_FLAG_RECALC)) {
+ /* evaluate this using values set already in other places */
+ // NOTE: for 'layering' option later on, we should check if we should remove old value before adding new to only be done when drivers only changed
+ calculate_fcurve(fcu, ctime);
+ animsys_execute_fcurve(ptr, NULL, fcu);
+
+ /* clear recalc flag */
+ driver->flag &= ~DRIVER_FLAG_RECALC;
+ }
+ }
+ }
+}
+
+/* ***************************************** */
+/* Actions Evaluation */
+
+/* Evaluate Action (F-Curve Bag) */
+static void animsys_evaluate_action (PointerRNA *ptr, nAction *act, AnimMapper *remap, float ctime)
+{
+ /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
+ if (act == NULL) return;
+ if ((remap) && (remap->target != act)) remap= NULL;
+
+ /* calculate then execute each curve */
+ animsys_evaluate_fcurves(ptr, &act->curves, remap, ctime);
+}
+
+/* ***************************************** */
+/* NLA System - Evaluation */
+
+/* used for list of strips to accumulate at current time */
+typedef struct NlaEvalStrip {
+ struct NlaEvalStrip *next, *prev;
+
+ NlaTrack *track; /* track that this strip belongs to */
+ NlaStrip *strip; /* strip that's being used */
+ NlaStrip *sblend; /* strip that's being blended towards (if applicable) */
+
+ short track_index; /* the index of the track within the list */
+ short strip_mode; /* which end of the strip are we looking at */
+} NlaEvalStrip;
+
+/* bNlaEvalStrip->strip_mode */
+enum {
+ NES_TIME_BEFORE = -1,
+ NES_TIME_WITHIN,
+ NES_TIME_AFTER,
+ NES_TIME_AFTER_BLEND
+} eNlaEvalStrip_StripMode;
+
+
+/* temp channel for accumulating data from NLA (avoids needing to clear all values first) */
+// TODO: maybe this will be used as the 'cache' stuff needed for editable values too?
+typedef struct NlaEvalChannel {
+ struct NlaEvalChannel *next, *prev;
+
+ char *path; /* ready-to-use path (i.e. remapped already) */
+ int array_index; /* if applicable... */
+
+ float value; /* value of this channel */
+} NlaEvalChannel;
+
+
+/* ---------------------- */
+
+/* evaluate the F-Curves controlling settings for the NLA-strips (currently, not relinkable) */
+static void nlastrip_evaluate_fcurves (NlaStrip *strip, float ctime)
+{
+ //PointerRNA actstrip_ptr;
+ //FCurve *fcu;
+
+ /* create RNA-pointer needed to set values */
+ //RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &actstrip_ptr);
+
+ /* execute these settings as per normal */
+ //animsys_evaluate_fcurves(&actstrip_ptr, &strip->fcurves, NULL, ctime);
+}
+
+
+/* gets the strip active at the current time for a track */
+static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime)
+{
+ NlaStrip *strip, *astrip=NULL, *bstrip=NULL;
+ NlaEvalStrip *nes;
+ short side= 0;
+
+ /* skip if track is muted */
+ if (nlt->flag & NLATRACK_MUTED)
+ return;
+
+ /* loop over strips, checking if they fall within the range */
+ for (strip= nlt->strips.first; strip; strip= strip->next) {
+ /* only consider if:
+ * - current time occurs within strip's extents
+ * - current time occurs before strip (if it is the first)
+ * - current time occurs after strip (if hold is on)
+ * - current time occurs between strips (1st of those isn't holding) - blend!
+ */
+ if (IN_RANGE(ctime, strip->start, strip->end)) {
+ astrip= strip;
+ side= NES_TIME_WITHIN;
+ break;
+ }
+ else if (ctime < strip->start) {
+ if (strip == nlt->strips.first) {
+ astrip= strip;
+ side= NES_TIME_BEFORE;
+ break;
+ }
+ else {
+ astrip= strip->prev;
+
+ if (astrip->flag & NLASTRIP_HOLDLASTFRAME) {
+ side= NES_TIME_AFTER;
+ break;
+ }
+ else {
+ bstrip= strip;
+ side= NES_TIME_AFTER_BLEND;
+ break;
+ }
+ }
+ }
+ }
+
+ /* check if strip has been found (and whether it has data worth considering) */
+ if (ELEM(NULL, astrip, astrip->act))
+ return;
+ if (astrip->flag & NLASTRIP_MUTE)
+ return;
+
+ /* check if blending between strips */
+ if (side == NES_TIME_AFTER_BLEND) {
+ /* blending between strips... so calculate influence+act_time of both */
+ nlastrip_evaluate_fcurves(astrip, ctime);
+ nlastrip_evaluate_fcurves(bstrip, ctime);
+
+ if ((astrip->influence <= 0.0f) && (bstrip->influence <= 0.0f))
+ return;
+ }
+ else {
+ /* calculate/set the influence+act_time of this strip - don't consider if 0 influence */
+ nlastrip_evaluate_fcurves(astrip, ctime);
+
+ if (astrip->influence <= 0.0f)
+ return;
+ }
+
+
+ /* allocate new eval-strip for this strip + add to stack */
+ nes= MEM_callocN(sizeof(NlaEvalStrip), "bNlaEvalStrip");
+
+ nes->track= nlt;
+ nes->strip= astrip;
+ nes->sblend= bstrip;
+ nes->track_index= index;
+ nes->strip_mode= side;
+
+ BLI_addtail(list, nes);
+}
+
+/* ---------------------- */
+
+/* evaluates the given evaluation strip */
+// FIXME: will we need the evaluation cache table set up to blend stuff in?
+// TODO: only evaluate here, but flush in one go using the accumulated channels at end...
+static void nlastrip_ctime_evaluate (ListBase *channels, NlaEvalStrip *nes, float ctime)
+{
+ // 1. (in old code) was to extract 'IPO-channels' from actions
+ // 2. blend between the 'accumulated' data, and the new data
+}
+
+/* write the accumulated settings to */
+static void nladata_flush_channels (PointerRNA *ptr, ListBase *channels)
+{
+
+}
+
+/* ---------------------- */
+
+/* NLA Evaluation function (mostly for use through do_animdata)
+ * - All channels that will be affected are not cleared anymore. Instead, we just evaluate into
+ * some temp channels, where values can be accumulated in one go.
+ */
+static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime)
+{
+ NlaTrack *nlt;
+ short track_index=0;
+
+ ListBase estrips= {NULL, NULL};
+ ListBase echannels= {NULL, NULL};
+ NlaEvalStrip *nes;
+
+ /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
+ for (nlt=adt->nla_tracks.first; nlt; nlt=nlt->next, track_index++)
+ nlatrack_ctime_get_strip(&estrips, nlt, track_index, ctime);
+
+ /* only continue if there are strips to evaluate */
+ if (estrips.first == NULL)
+ return;
+
+
+ /* 2. for each strip, evaluate then accumulate on top of existing channels, but don't set values yet */
+ for (nes= estrips.first; nes; nes= nes->next)
+ nlastrip_ctime_evaluate(&echannels, nes, ctime);
+
+ /* 3. flush effects of accumulating channels in NLA to the actual data they affect */
+ nladata_flush_channels(ptr, &echannels);
+
+ /* 4. free temporary evaluation data */
+ BLI_freelistN(&estrips);
+ BLI_freelistN(&echannels);
+}
+
+/* ***************************************** */
+/* Overrides System - Public API */
+
+/* Clear all overides */
+
+/* Add or get existing Override for given setting */
+AnimOverride *BKE_animsys_validate_override (PointerRNA *ptr, char *path, int array_index)
+{
+ // FIXME: need to define how to get overrides
+ return NULL;
+}
+
+/* -------------------- */
+
+/* Evaluate Overrides */
+static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt, float ctime)
+{
+ AnimOverride *aor;
+
+ /* for each override, simply execute... */
+ for (aor= adt->overrides.first; aor; aor= aor->next)
+ animsys_write_rna_setting(ptr, aor->rna_path, aor->array_index, aor->value);
+}
+
+/* ***************************************** */
+/* Evaluation System - Public API */
+
+/* Overview of how this system works:
+ * 1) Depsgraph sorts data as necessary, so that data is in an order that means
+ * that all dependences are resolved before dependants.
+ * 2) All normal animation is evaluated, so that drivers have some basis values to
+ * work with
+ * a. NLA stacks are done first, as the Active Actions act as 'tweaking' tracks
+ * which modify the effects of the NLA-stacks
+ * b. Active Action is evaluated as per normal, on top of the results of the NLA tracks
+ *
+ * --------------< often in a separate phase... >------------------
+ *
+ * 3) Drivers/expressions are evaluated on top of this, in an order where dependences are
+ * resolved nicely.
+ * Note: it may be necessary to have some tools to handle the cases where some higher-level
+ * drivers are added and cause some problematic dependencies that didn't exist in the local levels...
+ *
+ * --------------< always executed >------------------
+ *
+ * Maintainance of editability of settings (XXX):
+ * In order to ensure that settings that are animated can still be manipulated in the UI without requiring
+ * that keyframes are added to prevent these values from being overwritten, we use 'overrides'.
+ *
+ * Unresolved things:
+ * - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids or nodal system? but stored where?
+ * - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
+ */
+
+/* Evaluation loop for evaluation animation data
+ *
+ * This assumes that the animation-data provided belongs to the ID block in question,
+ * and that the flags for which parts of the anim-data settings need to be recalculated
+ * have been set already by the depsgraph. Now, we use the recalc
+ */
+void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short recalc)
+{
+ PointerRNA id_ptr;
+
+ /* sanity checks */
+ if ELEM(NULL, id, adt)
+ return;
+
+ /* get pointer to ID-block for RNA to use */
+ RNA_id_pointer_create(id, &id_ptr);
+
+ /* recalculate keyframe data:
+ * - NLA before Active Action, as Active Action behaves as 'tweaking track'
+ * that overrides 'rough' work in NLA
+ */
+ if ((recalc & ADT_RECALC_ANIM) /*|| (adt->recalc & ADT_RECALC_ANIM)*/) // XXX for now,don't check yet, as depsgraph doesn't know this yet
+ {
+ /* evaluate NLA data */
+ if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF))
+ {
+ animsys_evaluate_nla(&id_ptr, adt, ctime);
+ }
+
+ /* evaluate Action data */
+ // FIXME: what if the solo track was not tweaking one, then nla-solo should be checked too?
+ if (adt->action)
+ animsys_evaluate_action(&id_ptr, adt->action, adt->remap, ctime);
+ }
+
+ /* recalculate drivers
+ * - Drivers need to be evaluated afterwards, as they can either override
+ * or be layered on top of existing animation data.
+ * - Drivers should be in the appropriate order to be evaluated without problems...
+ */
+ if ((recalc & ADT_RECALC_DRIVERS) && (adt->recalc & ADT_RECALC_DRIVERS))
+ {
+ animsys_evaluate_drivers(&id_ptr, adt, ctime);
+ }
+
+ /* always execute 'overrides'
+ * - Overrides allow editing, by overwriting the value(s) set from animation-data, with the
+ * value last set by the user (and not keyframed yet).
+ * - Overrides are cleared upon frame change and/or keyframing
+ * - It is best that we execute this everytime, so that no errors are likely to occur.
+ */
+ animsys_evaluate_overrides(&id_ptr, adt, ctime);
+
+ /* clear recalc flag now */
+ adt->recalc= 0;
+}
+
+/* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only
+ *
+ * This will evaluate only the animation info available in the animation data-blocks
+ * encountered. In order to enforce the system by which some settings controlled by a
+ * 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a
+ * standard 'root') block are overridden by a larger 'user'
+ */
+// TODO: we currently go over entire 'main' database...
+void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
+{
+ ID *id;
+
+ //printf("Evaluate all animation - %f \n", ctime);
+
+ /* cameras */
+
+ /* textures */
+
+ /* lamps */
+
+ /* materials */
+
+ /* objects */
+ for (id= main->object.first; id; id= id->next) {
+ IdAdtTemplate *iat= (IdAdtTemplate *)id;
+ BKE_animsys_evaluate_animdata(id, &iat->adt, ctime, ADT_RECALC_ANIM);
+ }
+}
+
+/* ***************************************** */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 65225471d0f..d256e8dc8e7 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2231,9 +2231,6 @@ static void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, fl
if (pchan->constraints.first) {
bConstraintOb *cob;
- /* local constraints */
- do_constraint_channels(&pchan->constraints, NULL, ctime, 0);
-
/* make a copy of location of PoseChannel for later */
VECCOPY(vec, pchan->pose_mat[3]);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index f83428766f9..f5613a34700 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -80,157 +80,6 @@
#endif
-/* ******************* Constraint Channels ********************** */
-/* Constraint Channels exist in one of two places:
- * - Under Action Channels in an Action (act->chanbase->achan->constraintChannels)
- * - Under Object without Object-level Action yet (ob->constraintChannels)
- *
- * The main purpose that Constraint Channels serve is to act as a link
- * between an IPO-block (which provides values to interpolate between for some settings)
- */
-
-/* ------------ Data Management ----------- */
-
-/* Free constraint channels, and reduce the number of users of the related ipo-blocks */
-void free_constraint_channels (ListBase *chanbase)
-{
- bConstraintChannel *chan;
-
- for (chan=chanbase->first; chan; chan=chan->next) {
- if (chan->ipo) {
- chan->ipo->id.us--;
- }
- }
-
- BLI_freelistN(chanbase);
-}
-
-/* Make a copy of the constraint channels from dst to src, and also give the
- * new constraint channels their own copy of the original's IPO.
- */
-void copy_constraint_channels (ListBase *dst, ListBase *src)
-{
- bConstraintChannel *dchan, *schan;
-
- dst->first = dst->last = NULL;
- BLI_duplicatelist(dst, src);
-
- for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next) {
- dchan->ipo = copy_ipo(schan->ipo);
- }
-}
-
-/* Make a copy of the constraint channels from dst to src, but make the
- * new constraint channels use the same IPO-data as their twin.
- */
-void clone_constraint_channels (ListBase *dst, ListBase *src)
-{
- bConstraintChannel *dchan, *schan;
-
- dst->first = dst->last = NULL;
- BLI_duplicatelist(dst, src);
-
- for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next) {
- id_us_plus((ID *)dchan->ipo);
- }
-}
-
-/* ------------- Constraint Channel Tools ------------ */
-
-/* Find the constraint channel with a given name */
-bConstraintChannel *get_constraint_channel (ListBase *list, const char name[])
-{
- bConstraintChannel *chan;
-
- if (list) {
- for (chan = list->first; chan; chan=chan->next) {
- if (!strcmp(name, chan->name)) {
- return chan;
- }
- }
- }
-
- return NULL;
-}
-
-/* Find or create a 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 channel");
- BLI_addtail(list, chan);
- strcpy(chan->name, name);
- }
-
- return chan;
-}
-
-/* --------- Constraint Channel Evaluation/Execution --------- */
-
-/* IPO-system call: calculate IPO-block for constraint channels, and flush that
- * info onto the corresponding constraint.
- */
-void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, short onlydrivers)
-{
- bConstraint *con;
-
- /* for each Constraint, calculate its Influence from the corresponding ConstraintChannel */
- for (con=conbase->first; con; con=con->next) {
- Ipo *ipo= NULL;
-
- if (con->flag & CONSTRAINT_OWN_IPO)
- ipo= con->ipo;
- else {
- bConstraintChannel *chan = get_constraint_channel(chanbase, con->name);
- if (chan) ipo= chan->ipo;
- }
-
- if (ipo) {
- IpoCurve *icu;
-
- calc_ipo(ipo, ctime);
-
- for (icu=ipo->curve.first; icu; icu=icu->next) {
- if (!onlydrivers || icu->driver) {
- switch (icu->adrcode) {
- case CO_ENFORCE:
- {
- /* Influence is clamped to 0.0f -> 1.0f range */
- con->enforce = CLAMPIS(icu->curval, 0.0f, 1.0f);
- }
- break;
- case CO_HEADTAIL:
- {
- /* we need to check types of constraints that can get this here, as user
- * may have created an IPO-curve for this from IPO-editor but for a constraint
- * that cannot support this
- */
- switch (con->type) {
- /* supported constraints go here... */
- case CONSTRAINT_TYPE_LOCLIKE:
- case CONSTRAINT_TYPE_TRACKTO:
- case CONSTRAINT_TYPE_MINMAX:
- case CONSTRAINT_TYPE_STRETCHTO:
- case CONSTRAINT_TYPE_DISTLIMIT:
- con->headtail = icu->curval;
- break;
-
- default:
- /* not supported */
- break;
- }
- }
- break;
- }
- }
- }
- }
- }
-}
/* ************************ Constraints - General Utilities *************************** */
/* These functions here don't act on any specific constraints, and are therefore should/will
@@ -1303,10 +1152,12 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
if (cu->path && cu->path->data) {
curvetime= bsystem_time(cob->scene, ct->tar, (float)ctime, 0.0) - data->offset;
+#if 0 // XXX old animation system
if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
curvetime /= cu->pathlen;
CLAMP(curvetime, 0.0, 1.0);
}
+#endif // XXX old animation system
if ( where_on_path(ct->tar, curvetime, vec, dir) ) {
if (data->followflag) {
@@ -2053,7 +1904,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
Object workob;
/* evaluate using workob */
- what_does_obaction(cob->scene, cob->ob, &workob, data->act, t);
+ //what_does_obaction(cob->scene, cob->ob, &workob, data->act, t); // FIXME: missing func...
object_to_mat4(&workob, ct->matrix);
}
else {
@@ -3550,7 +3401,7 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
if (con->enforce == 0.0f) continue;
/* influence of constraint
- * - value should have been set from IPO's/Constraint Channels already
+ * - value should have been set from animation data already
*/
enf = con->enforce;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 4fba2c3d746..d52d91e40e9 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -49,7 +49,6 @@
/* for dereferencing pointers */
#include "DNA_ID.h"
#include "DNA_key_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -57,7 +56,6 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -85,8 +83,10 @@ void unlink_curve(Curve *cu)
cu->vfont= 0;
if(cu->key) cu->key->id.us--;
cu->key= 0;
+#if 0 // XXX old animation system
if(cu->ipo) cu->ipo->id.us--;
cu->ipo= 0;
+#endif // XXX old animation system
}
@@ -162,8 +162,10 @@ Curve *copy_curve(Curve *cu)
cun->bev.first= cun->bev.last= 0;
cun->path= 0;
+#if 0 // XXX old animation system
/* single user ipo too */
if(cun->ipo) cun->ipo= copy_ipo(cun->ipo);
+#endif // XXX old animation system
id_us_plus((ID *)cun->vfont);
id_us_plus((ID *)cun->vfontb);
@@ -1981,7 +1983,7 @@ void makeBevelList(Object *ob)
* 1: nothing, 1:auto, 2:vector, 3:aligned
*/
-/* mode: is not zero when IpoCurve, is 2 when forced horizontal for autohandles */
+/* mode: is not zero when FCurve, is 2 when forced horizontal for autohandles */
void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
{
float *p1,*p2,*p3, pt[3];
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 01dd6c0c657..4567717ea7a 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -38,6 +38,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
@@ -1954,6 +1955,7 @@ static int object_modifiers_use_time(Object *ob)
static int exists_channel(Object *ob, char *name)
{
+#if 0 // XXX old animation system
bActionStrip *strip;
if(ob->action)
@@ -1963,14 +1965,32 @@ static int exists_channel(Object *ob, char *name)
for (strip=ob->nlastrips.first; strip; strip=strip->next)
if(get_action_channel(strip->act, name))
return 1;
+#endif // XXX old animation system
+
return 0;
}
-static void dag_object_time_update_flags(Object *ob)
+
+static short animdata_use_time(AnimData *adt)
{
+ NlaTrack *nlt;
- if(ob->ipo) ob->recalc |= OB_RECALC_OB;
- else if(ob->constraints.first) {
+ /* check action - only if assigned, and it has anim curves */
+ if (adt->action && adt->action->curves.first)
+ return 1;
+
+ /* check NLA tracks + strips */
+ for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
+ if (nlt->strips.first)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void dag_object_time_update_flags(Object *ob)
+{
+ if(ob->constraints.first) {
bConstraint *con;
for (con = ob->constraints.first; con; con=con->next) {
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
@@ -2000,6 +2020,7 @@ static void dag_object_time_update_flags(Object *ob)
if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
}
+#if 0 // XXX old animation system
if(ob->action || ob->nlastrips.first) {
/* since actions now are mixed, we set the recalcs on the safe side */
ob->recalc |= OB_RECALC_OB;
@@ -2016,6 +2037,8 @@ static void dag_object_time_update_flags(Object *ob)
}
}
}
+#endif // XXX old animation system
+ if(animdata_use_time(&ob->adt)) ob->recalc |= OB_RECALC;
if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
if((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
new file mode 100644
index 00000000000..0e94faf0c4d
--- /dev/null
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -0,0 +1,1492 @@
+/* Testing code for new animation system in 2.5
+ * Copyright 2009, Joshua Leung
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_anim_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "BKE_fcurve.h"
+#include "BKE_curve.h"
+#include "BKE_idprop.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_types.h"
+
+#ifndef DISABLE_PYTHON
+#include "BPY_extern.h" /* for BPY_pydriver_eval() */
+#endif
+
+#define SMALL -1.0e-10
+#define SELECT 1
+
+/* ************************** Data-Level Functions ************************* */
+
+/* ---------------------- Freeing --------------------------- */
+
+/* Frees the F-Curve itself too */
+void free_fcurve (FCurve *fcu)
+{
+ if (fcu == NULL)
+ return;
+
+ /* free curve data */
+ if (fcu) {
+ if (fcu->bezt) MEM_freeN(fcu->bezt);
+ if (fcu->fpt) MEM_freeN(fcu->fpt);
+ }
+
+ /* free RNA-path, as this were allocated when getting the path string */
+ if (fcu->rna_path)
+ MEM_freeN(fcu->rna_path);
+
+ /* free extra data - i.e. modifiers, and driver */
+ fcurve_free_driver(fcu);
+ fcurve_free_modifiers(fcu);
+
+ /* free f-cruve itself */
+ MEM_freeN(fcu);
+}
+
+/* ---------------------- Copy --------------------------- */
+
+/* duplicate an F-Curve */
+FCurve *copy_fcurve (FCurve *fcu)
+{
+ FCurve *fcu_d;
+
+ /* sanity check */
+ if (fcu == NULL)
+ return NULL;
+
+ /* make a copy */
+ fcu_d= MEM_dupallocN(fcu);
+
+ /* copy curve data */
+ fcu_d->bezt= MEM_dupallocN(fcu_d->bezt);
+ fcu_d->fpt= MEM_dupallocN(fcu_d->fpt);
+
+ /* copy rna-path */
+ fcu_d->rna_path= MEM_dupallocN(fcu_d->rna_path);
+
+ /* copy driver */
+ //fcurve_copy_driver();
+
+ /* copy modifiers */
+ fcurve_copy_modifiers(&fcu_d->modifiers, &fcu->modifiers);
+
+ /* return new data */
+ return fcu_d;
+}
+
+/* ---------------------- Relink --------------------------- */
+
+#if 0
+/* uses id->newid to match pointers with other copied data
+ * - called after single-user or other such
+ */
+ if (icu->driver)
+ ID_NEW(icu->driver->ob);
+#endif
+
+/* --------------------- Finding -------------------------- */
+
+/* Find the F-Curve affecting the given RNA-access path + index, in the list of F-Curves provided */
+FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array_index)
+{
+ FCurve *fcu;
+
+ /* sanity checks */
+ if ( ELEM(NULL, list, rna_path) || (array_index < 0) )
+ return NULL;
+
+ /* check paths of curves, then array indices... */
+ for (fcu= list->first; fcu; fcu= fcu->next) {
+ /* simple string-compare (this assumes that they have the same root...) */
+ if (strcmp(fcu->rna_path, rna_path) == 0) {
+ /* now check indicies */
+ if (fcu->array_index == array_index)
+ return fcu;
+ }
+ }
+
+ /* return */
+ return NULL;
+}
+
+/* ***************************** Keyframe Column Tools ********************************* */
+
+/* add a BezTriple to a column */
+void bezt_add_to_cfra_elem (ListBase *lb, BezTriple *bezt)
+{
+ CfraElem *ce, *cen;
+
+ for (ce= lb->first; ce; ce= ce->next) {
+ /* double key? */
+ if (ce->cfra == bezt->vec[1][0]) {
+ if (bezt->f2 & SELECT) ce->sel= bezt->f2;
+ return;
+ }
+ /* should key be inserted before this column? */
+ else if (ce->cfra > bezt->vec[1][0]) break;
+ }
+
+ /* create a new column */
+ cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
+ if (ce) BLI_insertlinkbefore(lb, ce, cen);
+ else BLI_addtail(lb, cen);
+
+ cen->cfra= bezt->vec[1][0];
+ cen->sel= bezt->f2;
+}
+
+/* ***************************** F-Curve Sanity ********************************* */
+/* The functions here are used in various parts of Blender, usually after some editing
+ * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
+ * that the handles are correctly
+ */
+
+/* This function recalculates the handles of an F-Curve
+ * If the BezTriples have been rearranged, sort them first before using this.
+ */
+void calchandles_fcurve (FCurve *fcu)
+{
+ BezTriple *bezt, *prev, *next;
+ int a= fcu->totvert;
+
+ /* Error checking:
+ * - need at least two points
+ * - need bezier keys
+ * - only bezier-interpolation has handles (for now)
+ */
+ if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN)*/)
+ return;
+
+ /* get initial pointers */
+ bezt= fcu->bezt;
+ prev= NULL;
+ next= (bezt + 1);
+
+ /* loop over all beztriples, adjusting handles */
+ while (a--) {
+ /* clamp timing of handles to be on either side of beztriple */
+ if (bezt->vec[0][0] > bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
+ if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
+
+ /* calculate auto-handles */
+ if (fcu->flag & FCURVE_AUTO_HANDLES)
+ calchandleNurb(bezt, prev, next, 2); /* 2==special autohandle && keep extrema horizontal */
+ else
+ calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */
+
+ /* for automatic ease in and out */
+ if ((bezt->h1==HD_AUTO) && (bezt->h2==HD_AUTO)) {
+ /* only do this on first or last beztriple */
+ if ((a == 0) || (a == fcu->totvert-1)) {
+ /* set both handles to have same horizontal value as keyframe */
+ if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
+ bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
+ }
+ }
+ }
+
+ /* advance pointers for next iteration */
+ prev= bezt;
+ if (a == 1) next= NULL;
+ else next++;
+ bezt++;
+ }
+}
+
+/* Use when F-Curve with handles has changed
+ * It treats all BezTriples with the following rules:
+ * - PHASE 1: do types have to be altered?
+ * -> Auto handles: become aligned when selection status is NOT(000 || 111)
+ * -> Vector handles: become 'nothing' when (one half selected AND other not)
+ * - PHASE 2: recalculate handles
+*/
+void testhandles_fcurve (FCurve *fcu)
+{
+ BezTriple *bezt;
+ int a;
+
+ /* only beztriples have handles (bpoints don't though) */
+ if ELEM(NULL, fcu, fcu->bezt)
+ return;
+
+ /* loop over beztriples */
+ for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
+ short flag= 0;
+
+ /* flag is initialised as selection status
+ * of beztriple control-points (labelled 0,1,2)
+ */
+ if (bezt->f1 & SELECT) flag |= (1<<0); // == 1
+ if (bezt->f2 & SELECT) flag |= (1<<1); // == 2
+ if (bezt->f3 & SELECT) flag |= (1<<2); // == 4
+
+ /* one or two handles selected only */
+ if (ELEM(flag, 0, 7)==0) {
+ /* auto handles become aligned */
+ if (bezt->h1==HD_AUTO)
+ bezt->h1= HD_ALIGN;
+ if (bezt->h2==HD_AUTO)
+ bezt->h2= HD_ALIGN;
+
+ /* vector handles become 'free' when only one half selected */
+ if (bezt->h1==HD_VECT) {
+ /* only left half (1 or 2 or 1+2) */
+ if (flag < 4)
+ bezt->h1= 0;
+ }
+ if (bezt->h2==HD_VECT) {
+ /* only right half (4 or 2+4) */
+ if (flag > 3)
+ bezt->h2= 0;
+ }
+ }
+ }
+
+ /* recalculate handles */
+ calchandles_fcurve(fcu);
+}
+
+/* This function sorts BezTriples so that they are arranged in chronological order,
+ * as tools working on F-Curves expect that the BezTriples are in order.
+ */
+void sort_time_fcurve (FCurve *fcu)
+{
+ short ok= 1;
+
+ /* keep adjusting order of beztriples until nothing moves (bubble-sort) */
+ while (ok) {
+ ok= 0;
+
+ /* currently, will only be needed when there are beztriples */
+ if (fcu->bezt) {
+ BezTriple *bezt;
+ int a;
+
+ /* loop over ALL points to adjust position in array and recalculate handles */
+ for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
+ /* check if thee's a next beztriple which we could try to swap with current */
+ if (a < (fcu->totvert-1)) {
+ /* swap if one is after the other (and indicate that order has changed) */
+ if (bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
+ SWAP(BezTriple, *bezt, *(bezt+1));
+ ok= 1;
+ }
+
+ /* if either one of both of the points exceeds crosses over the keyframe time... */
+ if ( (bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0]) ) {
+ /* swap handles if they have switched sides for some reason */
+ SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
+ SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
+ }
+ else {
+ /* clamp handles */
+ if (bezt->vec[0][0] > bezt->vec[1][0])
+ bezt->vec[0][0]= bezt->vec[1][0];
+ if (bezt->vec[2][0] < bezt->vec[1][0])
+ bezt->vec[2][0]= bezt->vec[1][0];
+ }
+ }
+ }
+ }
+ }
+}
+
+/* This function tests if any BezTriples are out of order, thus requiring a sort */
+short test_time_fcurve (FCurve *fcu)
+{
+ int a;
+
+ /* sanity checks */
+ if (fcu == NULL)
+ return 0;
+
+ /* currently, only need to test beztriples */
+ if (fcu->bezt) {
+ BezTriple *bezt;
+
+ /* loop through all BezTriples, stopping when one exceeds the one after it */
+ for (a=0, bezt= fcu->bezt; a < (fcu->totvert - 1); a++, bezt++) {
+ if (bezt->vec[1][0] > (bezt+1)->vec[1][0])
+ return 1;
+ }
+ }
+ else if (fcu->fpt) {
+ FPoint *fpt;
+
+ /* loop through all FPoints, stopping when one exceeds the one after it */
+ for (a=0, fpt= fcu->fpt; a < (fcu->totvert - 1); a++, fpt++) {
+ if (fpt->vec[0] > (fpt+1)->vec[0])
+ return 1;
+ }
+ }
+
+ /* none need any swapping */
+ return 0;
+}
+
+/* ***************************** Drivers ********************************* */
+
+/* Driver API --------------------------------- */
+
+/* This frees the driver itself */
+void fcurve_free_driver(FCurve *fcu)
+{
+ ChannelDriver *driver;
+
+ /* sanity checks */
+ if ELEM(NULL, fcu, fcu->driver)
+ return;
+ driver= fcu->driver;
+
+ /* free RNA-paths, as these were allocated when getting the path string */
+ if (driver->rna_path) MEM_freeN(driver->rna_path);
+ if (driver->rna_path2) MEM_freeN(driver->rna_path2);
+
+ /* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
+ MEM_freeN(driver);
+ fcu->driver= NULL;
+}
+
+/* Driver Evaluation -------------------------- */
+
+/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers)
+ * - target: used to specify which of the two driver-targets to use
+ */
+static float driver_get_driver_value (ChannelDriver *driver, short target)
+{
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ char *path;
+ int index;
+ float value= 0.0f;
+
+ /* get RNA-pointer for the ID-block given in driver */
+ if (target == 2) {
+ /* second target */
+ RNA_id_pointer_create(driver->id2, &id_ptr);
+ path= driver->rna_path2;
+ index= driver->array_index2;
+ }
+ else {
+ /* first/main target */
+ RNA_id_pointer_create(driver->id, &id_ptr);
+ path= driver->rna_path;
+ index= driver->array_index;
+ }
+
+ /* get property to read from, and get value as appropriate */
+ if (RNA_path_resolve(&id_ptr, path, &ptr, &prop)) {
+ switch (RNA_property_type(&ptr, prop)) {
+ case PROP_BOOLEAN:
+ if (RNA_property_array_length(&ptr, prop))
+ value= (float)RNA_property_boolean_get_array(&ptr, prop, index);
+ else
+ value= (float)RNA_property_boolean_get(&ptr, prop);
+ break;
+ case PROP_INT:
+ if (RNA_property_array_length(&ptr, prop))
+ value= (float)RNA_property_int_get_array(&ptr, prop, index);
+ else
+ value= (float)RNA_property_int_get(&ptr, prop);
+ break;
+ case PROP_FLOAT:
+ if (RNA_property_array_length(&ptr, prop))
+ value= RNA_property_float_get_array(&ptr, prop, index);
+ else
+ value= RNA_property_float_get(&ptr, prop);
+ break;
+ case PROP_ENUM:
+ value= (float)RNA_property_enum_get(&ptr, prop);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return value;
+}
+
+/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
+ * - "evaltime" is the frame at which F-Curve is being evaluated
+ * - has to return a float value
+ */
+static float evaluate_driver (ChannelDriver *driver, float evaltime)
+{
+ /* check if driver can be evaluated */
+ if (driver->flag & DRIVER_FLAG_DISABLED)
+ return 0.0f;
+
+ switch (driver->type) {
+ case DRIVER_TYPE_CHANNEL: /* channel/setting drivers channel/setting */
+ return driver_get_driver_value(driver, 0);
+
+#ifndef DISABLE_PYTHON
+ case DRIVER_TYPE_PYTHON: /* expression */
+ {
+ /* check for empty or invalid expression */
+ if ( (driver->expression[0] == '\0') ||
+ (driver->flag & DRIVER_FLAG_INVALID) )
+ {
+ return 0.0f;
+ }
+
+ /* this evaluates the expression using Python,and returns its result:
+ * - on errors it reports, then returns 0.0f
+ */
+ //return BPY_pydriver_eval(driver); // XXX old func
+ return 1.0f;
+ }
+#endif /* DISABLE_PYTHON*/
+
+ case DRIVER_TYPE_ROTDIFF: /* difference of rotations of 2 bones (should be in same armature) */
+ {
+ /*
+ float q1[4], q2[4], quat[4], angle;
+
+ Mat4ToQuat(pchan->pose_mat, q1);
+ Mat4ToQuat(pchan2->pose_mat, q2);
+
+ QuatInv(q1);
+ QuatMul(quat, q1, q2);
+ angle = 2.0f * (saacos(quat[0]));
+ angle= ABS(angle);
+
+ return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
+ */
+ }
+ break;
+
+ default:
+ {
+ /* special 'hack' - just use stored value
+ * This is currently used as the mechanism which allows animated settings to be able
+ * to be changed via the UI.
+ */
+ return driver->curval;
+ }
+ }
+
+ /* return 0.0f, as couldn't find relevant data to use */
+ return 0.0f;
+}
+
+/* ***************************** Curve Calculations ********************************* */
+
+/* The total length of the handles is not allowed to be more
+ * than the horizontal distance between (v1-v4).
+ * This is to prevent curve loops.
+*/
+void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
+{
+ float h1[2], h2[2], len1, len2, len, fac;
+
+ /* calculate handle deltas */
+ h1[0]= v1[0] - v2[0];
+ h1[1]= v1[1] - v2[1];
+
+ h2[0]= v4[0] - v3[0];
+ h2[1]= v4[1] - v3[1];
+
+ /* calculate distances:
+ * - len = span of time between keyframes
+ * - len1 = length of handle of start key
+ * - len2 = length of handle of end key
+ */
+ len= v4[0]- v1[0];
+ len1= (float)fabs(h1[0]);
+ len2= (float)fabs(h2[0]);
+
+ /* if the handles have no length, no need to do any corrections */
+ if ((len1+len2) == 0.0f)
+ return;
+
+ /* the two handles cross over each other, so force them
+ * apart using the proportion they overlap
+ */
+ if ((len1+len2) > len) {
+ fac= len / (len1+len2);
+
+ v2[0]= (v1[0] - fac*h1[0]);
+ v2[1]= (v1[1] - fac*h1[1]);
+
+ v3[0]= (v4[0] - fac*h2[0]);
+ v3[1]= (v4[1] - fac*h2[1]);
+ }
+}
+
+/* find root ('zero') */
+int findzero (float x, float q0, float q1, float q2, float q3, float *o)
+{
+ double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
+ int nr= 0;
+
+ c0= q0 - x;
+ c1= 3.0 * (q1 - q0);
+ c2= 3.0 * (q0 - 2.0*q1 + q2);
+ c3= q3 - q0 + 3.0 * (q1 - q2);
+
+ if (c3 != 0.0) {
+ a= c2/c3;
+ b= c1/c3;
+ c= c0/c3;
+ a= a/3;
+
+ p= b/3 - a*a;
+ q= (2*a*a*a - a*b + c) / 2;
+ d= q*q + p*p*p;
+
+ if (d > 0.0) {
+ t= sqrt(d);
+ o[0]= (float)(Sqrt3d(-q+t) + Sqrt3d(-q-t) - a);
+
+ if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
+ else return 0;
+ }
+ else if (d == 0.0) {
+ t= Sqrt3d(-q);
+ o[0]= (float)(2*t - a);
+
+ if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
+ o[nr]= (float)(-t-a);
+
+ if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
+ else return nr;
+ }
+ else {
+ phi= acos(-q / sqrt(-(p*p*p)));
+ t= sqrt(-p);
+ p= cos(phi/3);
+ q= sqrt(3 - 3*p*p);
+ o[0]= (float)(2*t*p - a);
+
+ if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
+ o[nr]= (float)(-t * (p + q) - a);
+
+ if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) nr++;
+ o[nr]= (float)(-t * (p - q) - a);
+
+ if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
+ else return nr;
+ }
+ }
+ else {
+ a=c2;
+ b=c1;
+ c=c0;
+
+ if (a != 0.0) {
+ // discriminant
+ p= b*b - 4*a*c;
+
+ if (p > 0) {
+ p= sqrt(p);
+ o[0]= (float)((-b-p) / (2 * a));
+
+ if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
+ o[nr]= (float)((-b+p)/(2*a));
+
+ if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
+ else return nr;
+ }
+ else if (p == 0) {
+ o[0]= (float)(-b / (2 * a));
+ if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
+ else return 0;
+ }
+ }
+ else if (b != 0.0) {
+ o[0]= (float)(-c/b);
+
+ if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
+ else return 0;
+ }
+ else if (c == 0.0) {
+ o[0]= 0.0;
+ return 1;
+ }
+
+ return 0;
+ }
+}
+
+void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
+{
+ float t, c0, c1, c2, c3;
+ int a;
+
+ c0= f1;
+ c1= 3.0f * (f2 - f1);
+ c2= 3.0f * (f1 - 2.0f*f2 + f3);
+ c3= f4 - f1 + 3.0f * (f2 - f3);
+
+ for (a=0; a < b; a++) {
+ t= o[a];
+ o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
+ }
+}
+
+void berekenx (float *f, float *o, int b)
+{
+ float t, c0, c1, c2, c3;
+ int a;
+
+ c0= f[0];
+ c1= 3.0f * (f[3] - f[0]);
+ c2= 3.0f * (f[0] - 2.0f*f[3] + f[6]);
+ c3= f[9] - f[0] + 3.0f * (f[3] - f[6]);
+
+ for (a=0; a < b; a++) {
+ t= o[a];
+ o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
+ }
+}
+
+
+/* -------------------------- */
+
+/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
+static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltime)
+{
+ BezTriple *bezt, *prevbezt, *lastbezt;
+ float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
+ int a, b;
+ float cvalue = 0.0f;
+
+ /* get pointers */
+ a= fcu->totvert-1;
+ prevbezt= bezts;
+ bezt= prevbezt+1;
+ lastbezt= prevbezt + a;
+
+ /* evaluation time at or past endpoints? */
+ if (prevbezt->vec[1][0] >= evaltime) {
+ /* before or on first keyframe */
+ if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST)) {
+ /* linear or bezier interpolation */
+ if (prevbezt->ipo==BEZT_IPO_LIN) {
+ /* Use the next center point instead of our own handle for
+ * linear interpolated extrapolate
+ */
+ if (fcu->totvert == 1)
+ cvalue= prevbezt->vec[1][1];
+ else {
+ bezt = prevbezt+1;
+ dx= prevbezt->vec[1][0] - evaltime;
+ fac= bezt->vec[1][0] - prevbezt->vec[1][0];
+
+ /* prevent division by zero */
+ if (fac) {
+ fac= (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
+ cvalue= prevbezt->vec[1][1] - (fac * dx);
+ }
+ else
+ cvalue= prevbezt->vec[1][1];
+ }
+ }
+ else {
+ /* Use the first handle (earlier) of first BezTriple to calculate the
+ * gradient and thus the value of the curve at evaltime
+ */
+ dx= prevbezt->vec[1][0] - evaltime;
+ fac= prevbezt->vec[1][0] - prevbezt->vec[0][0];
+
+ /* prevent division by zero */
+ if (fac) {
+ fac= (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
+ cvalue= prevbezt->vec[1][1] - (fac * dx);
+ }
+ else
+ cvalue= prevbezt->vec[1][1];
+ }
+ }
+ else {
+ /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
+ * so just extend first keyframe's value
+ */
+ cvalue= prevbezt->vec[1][1];
+ }
+ }
+ else if (lastbezt->vec[1][0] <= evaltime) {
+ /* after or on last keyframe */
+ if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST)) {
+ /* linear or bezier interpolation */
+ if (lastbezt->ipo==BEZT_IPO_LIN) {
+ /* Use the next center point instead of our own handle for
+ * linear interpolated extrapolate
+ */
+ if (fcu->totvert == 1)
+ cvalue= lastbezt->vec[1][1];
+ else {
+ prevbezt = lastbezt - 1;
+ dx= evaltime - lastbezt->vec[1][0];
+ fac= lastbezt->vec[1][0] - prevbezt->vec[1][0];
+
+ /* prevent division by zero */
+ if (fac) {
+ fac= (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
+ cvalue= lastbezt->vec[1][1] + (fac * dx);
+ }
+ else
+ cvalue= lastbezt->vec[1][1];
+ }
+ }
+ else {
+ /* Use the gradient of the second handle (later) of last BezTriple to calculate the
+ * gradient and thus the value of the curve at evaltime
+ */
+ dx= evaltime - lastbezt->vec[1][0];
+ fac= lastbezt->vec[2][0] - lastbezt->vec[1][0];
+
+ /* prevent division by zero */
+ if (fac) {
+ fac= (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
+ cvalue= lastbezt->vec[1][1] + (fac * dx);
+ }
+ else
+ cvalue= lastbezt->vec[1][1];
+ }
+ }
+ else {
+ /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
+ * so just extend last keyframe's value
+ */
+ cvalue= lastbezt->vec[1][1];
+ }
+ }
+ else {
+ /* evaltime occurs somewhere in the middle of the curve */
+ for (a=0; prevbezt && bezt && (a < fcu->totvert-1); a++, prevbezt=bezt, bezt++) {
+ /* evaltime occurs within the interval defined by these two keyframes */
+ if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
+ /* value depends on interpolation mode */
+ if (prevbezt->ipo == BEZT_IPO_CONST) {
+ /* constant (evaltime not relevant, so no interpolation needed) */
+ cvalue= prevbezt->vec[1][1];
+ }
+ else if (prevbezt->ipo == BEZT_IPO_LIN) {
+ /* linear - interpolate between values of the two keyframes */
+ fac= bezt->vec[1][0] - prevbezt->vec[1][0];
+
+ /* prevent division by zero */
+ if (fac) {
+ fac= (evaltime - prevbezt->vec[1][0]) / fac;
+ cvalue= prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
+ }
+ else
+ cvalue= prevbezt->vec[1][1];
+ }
+ else {
+ /* bezier interpolation */
+ /* v1,v2 are the first keyframe and its 2nd handle */
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
+ v2[0]= prevbezt->vec[2][0];
+ v2[1]= prevbezt->vec[2][1];
+ /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
+ v3[0]= bezt->vec[0][0];
+ v3[1]= bezt->vec[0][1];
+ v4[0]= bezt->vec[1][0];
+ v4[1]= bezt->vec[1][1];
+
+ /* adjust handles so that they don't overlap (forming a loop) */
+ correct_bezpart(v1, v2, v3, v4);
+
+ /* try to get a value for this position - if failure, try another set of points */
+ b= findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+ if (b) {
+ berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+ cvalue= opl[0];
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* return value */
+ return cvalue;
+}
+
+/* Calculate F-Curve value for 'evaltime' using FPoint samples */
+static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime)
+{
+ FPoint *prevfpt, *lastfpt, *fpt;
+ float cvalue= 0.0f;
+
+ /* get pointers */
+ prevfpt= fpts;
+ lastfpt= prevfpt + fcu->totvert-1;
+
+ /* evaluation time at or past endpoints? */
+ if (prevfpt->vec[0] >= evaltime) {
+ /* before or on first sample, so just extend value */
+ cvalue= prevfpt->vec[1];
+ }
+ else if (lastfpt->vec[0] <= evaltime) {
+ /* after or on last sample, so just extend value */
+ cvalue= lastfpt->vec[1];
+ }
+ else {
+ /* find the one on the right frame (assume that these are spaced on 1-frame intervals) */
+ fpt= prevfpt + (int)(evaltime - prevfpt->vec[0]);
+ cvalue= fpt->vec[1];
+ }
+
+ /* return value */
+ return cvalue;
+}
+
+/* ******************************** F-Curve Modifiers ********************************* */
+
+/* Template --------------------------- */
+
+/* Each modifier defines a set of functions, which will be called at the appropriate
+ * times. In addition to this, each modifier should have a type-info struct, where
+ * its functions are attached for use.
+ */
+
+/* Template for type-info data:
+ * - make a copy of this when creating new modifiers, and just change the functions
+ * pointed to as necessary
+ * - although the naming of functions doesn't matter, it would help for code
+ * readability, to follow the same naming convention as is presented here
+ * - any functions that a constraint doesn't need to define, don't define
+ * for such cases, just use NULL
+ * - these should be defined after all the functions have been defined, so that
+ * forward-definitions/prototypes don't need to be used!
+ * - keep this copy #if-def'd so that future constraints can get based off this
+ */
+#if 0
+static FModifierTypeInfo FMI_MODNAME = {
+ FMODIFIER_TYPE_MODNAME, /* type */
+ sizeof(FMod_ModName), /* size */
+ "Modifier Name", /* name */
+ "FMod_ModName", /* struct name */
+ fcm_modname_free, /* free data */
+ fcm_modname_relink, /* relink data */
+ fcm_modname_copy, /* copy data */
+ fcm_modname_new_data, /* new data */
+ fcm_modname_evaluate /* evaluate */
+};
+#endif
+
+/* Generator F-Curve Modifier --------------------------- */
+
+static void fcm_generator_free (FModifier *fcm)
+{
+ FMod_Generator *data= (FMod_Generator *)fcm->data;
+
+ /* free polynomial coefficients array */
+ if (data->poly_coefficients)
+ MEM_freeN(data->poly_coefficients);
+}
+
+static void fcm_generator_copy (FModifier *fcm, FModifier *src)
+{
+ FMod_Generator *gen= (FMod_Generator *)fcm->data;
+ FMod_Generator *ogen= (FMod_Generator *)src->data;
+
+ /* copy polynomial coefficients array? */
+ if (ogen->poly_coefficients)
+ gen->poly_coefficients= MEM_dupallocN(ogen->poly_coefficients);
+}
+
+static void fcm_generator_new_data (void *mdata)
+{
+ FMod_Generator *data= (FMod_Generator *)mdata;
+ float *cp;
+
+ /* set default generator to be linear 0-1 (gradient = 1, y-offset = 0) */
+ data->poly_order= 1;
+ cp= data->poly_coefficients= MEM_callocN(sizeof(float)*2, "FMod_Generator_Coefs");
+ cp[0] = 0; // y-offset
+ cp[1] = 1; // gradient
+}
+
+
+static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+ FMod_Generator *data= (FMod_Generator *)fcm->data;
+
+ /* behaviour depends on mode (NOTE: we don't need to do anything...) */
+ switch (data->mode) {
+ case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ {
+ /* we overwrite cvalue with the sum of the polynomial */
+ float value= 0.0f, *cp = NULL;
+ unsigned int i;
+
+ /* for each coefficient, add to value, which we'll write to *cvalue in one go */
+ // TODO: could this be more efficient (i.e. without need to recalc pow() everytime)
+ cp= data->poly_coefficients;
+ for (i=0; (i <= data->poly_order) && (cp); i++, cp++)
+ value += (*cp) * pow(evaltime, i);
+
+ /* only if something changed */
+ if (data->poly_order)
+ *cvalue= value;
+ }
+ break;
+
+#ifndef DISABLE_PYTHON
+ case FCM_GENERATOR_EXPRESSION: /* py-expression */
+ // TODO...
+ break;
+#endif /* DISABLE_PYTHON */
+ }
+}
+
+static FModifierTypeInfo FMI_GENERATOR = {
+ FMODIFIER_TYPE_GENERATOR, /* type */
+ sizeof(FMod_Generator), /* size */
+ "Generator", /* name */
+ "FMod_Generator", /* struct name */
+ fcm_generator_free, /* free data */
+ fcm_generator_copy, /* copy data */
+ fcm_generator_new_data, /* new data */
+ fcm_generator_evaluate /* evaluate */
+};
+
+/* Envelope F-Curve Modifier --------------------------- */
+
+static void fcm_envelope_free (FModifier *fcm)
+{
+ FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+
+ /* free envelope data array */
+ if (data->data)
+ MEM_freeN(data->data);
+}
+
+static void fcm_envelope_copy (FModifier *fcm, FModifier *src)
+{
+ FMod_Envelope *gen= (FMod_Envelope *)fcm->data;
+ FMod_Envelope *ogen= (FMod_Envelope *)src->data;
+
+ /* copy envelope data array */
+ if (ogen->data)
+ gen->data= MEM_dupallocN(ogen->data);
+}
+
+static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+ FMod_Envelope *env= (FMod_Envelope *)fcm->data;
+ FCM_EnvelopeData *fed, *prevfed, *lastfed;
+ float min=0.0f, max=0.0f, fac=0.0f;
+ int a;
+
+ /* get pointers */
+ if (env->data == NULL) return;
+ prevfed= env->data;
+ fed= prevfed + 1;
+ lastfed= prevfed + env->totvert-1;
+
+ /* get min/max values for envelope at evaluation time (relative to mid-value) */
+ if (prevfed->time >= evaltime) {
+ /* before or on first sample, so just extend value */
+ min= prevfed->min;
+ max= prevfed->max;
+ }
+ else if (lastfed->time <= evaltime) {
+ /* after or on last sample, so just extend value */
+ min= lastfed->min;
+ max= lastfed->max;
+ }
+ else {
+ /* evaltime occurs somewhere between segments */
+ for (a=0; prevfed && fed && (a < env->totvert-1); a++, prevfed=fed, fed++) {
+ /* evaltime occurs within the interval defined by these two envelope points */
+ if ((prevfed->time <= evaltime) && (fed->time >= evaltime)) {
+ float afac, bfac, diff;
+
+ diff= fed->time - prevfed->time;
+ afac= (evaltime - prevfed->time) / diff;
+ bfac= (fed->time - evaltime)/(diff);
+
+ min= afac*prevfed->min + bfac*fed->min;
+ max= afac*prevfed->max + bfac*fed->max;
+
+ break;
+ }
+ }
+ }
+
+ /* adjust *cvalue
+ * NOTE: env->min/max are relative to env->midval, and can be either +ve OR -ve, so we add...
+ */
+ fac= (*cvalue - min) / (max - min);
+ *cvalue= (env->midval + env->min) + (fac * (env->max - env->min));
+}
+
+static FModifierTypeInfo FMI_ENVELOPE = {
+ FMODIFIER_TYPE_ENVELOPE, /* type */
+ sizeof(FMod_Envelope), /* size */
+ "Envelope", /* name */
+ "FMod_Envelope", /* struct name */
+ fcm_envelope_free, /* free data */
+ fcm_envelope_copy, /* copy data */
+ NULL, /* new data */
+ fcm_envelope_evaluate /* evaluate */
+};
+
+/* Cycles F-Curve Modifier --------------------------- */
+
+/* This modifier changes evaltime to something that exists within the curve's frame-range,
+ * then re-evaluates modifier stack up to this point using the new time. This re-entrant behaviour
+ * is very likely to be more time-consuming than the original approach... (which was tighly integrated into
+ * the calculation code...).
+ *
+ * NOTE: this needs to be at the start of the stack to be of use, as it needs to know the extents of the keyframes/sample-data
+ * Possible TODO - store length of cycle information that can be initialised from the extents of the keyframes/sample-data, and adjusted
+ * as appropriate
+ */
+
+static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+ FMod_Cycles *data= (FMod_Cycles *)fcm->data;
+ ListBase mods = {NULL, NULL};
+ float prevkey[2], lastkey[2], cycyofs=0.0f;
+ float new_value;
+ short side=0, mode=0;
+ int cycles=0;
+
+ /* check if modifier is first in stack, otherwise disable ourself... */
+ // FIXME...
+ if (fcm->prev) {
+ fcm->flag |= FMODIFIER_FLAG_DISABLED;
+ return;
+ }
+
+ /* calculate new evaltime due to cyclic interpolation */
+ if (fcu && fcu->bezt) {
+ BezTriple *prevbezt= fcu->bezt;
+ BezTriple *lastbezt= prevbezt + fcu->totvert-1;
+
+ prevkey[0]= prevbezt->vec[1][0];
+ prevkey[1]= prevbezt->vec[1][1];
+
+ lastkey[0]= lastbezt->vec[1][0];
+ lastkey[1]= lastbezt->vec[1][1];
+ }
+ else if (fcu && fcu->fpt) {
+ FPoint *prevfpt= fcu->fpt;
+ FPoint *lastfpt= prevfpt + fcu->totvert-1;
+
+ prevkey[0]= prevfpt->vec[0];
+ prevkey[1]= prevfpt->vec[1];
+
+ lastkey[0]= lastfpt->vec[0];
+ lastkey[1]= lastfpt->vec[1];
+ }
+ else
+ return;
+
+ /* check if modifier will do anything
+ * 1) if in data range, definitely don't do anything
+ * 2) if before first frame or after last frame, make sure some cycling is in use
+ */
+ if (evaltime < prevkey[0]) {
+ if (data->before_mode) {
+ side= -1;
+ mode= data->before_mode;
+ cycles= data->before_cycles;
+ }
+ }
+ else if (evaltime > lastkey[0]) {
+ if (data->after_mode) {
+ side= 1;
+ mode= data->after_mode;
+ cycles= data->after_cycles;
+ }
+ }
+ if ELEM3(0, side, mode, cycles)
+ return;
+
+ /* extrapolation mode is 'cyclic' - find relative place within a cycle */
+ // FIXME: adding the more fine-grained control of extrpolation mode
+ {
+ float cycdx=0, cycdy=0, ofs=0;
+
+ /* ofs is start frame of cycle */
+ ofs= prevkey[0];
+
+ /* calculate period and amplitude (total height) of a cycle */
+ cycdx= lastkey[0] - prevkey[0];
+ cycdy= lastkey[1] - prevkey[1];
+
+ /* check if cycle is infinitely small, to be point of being impossible to use */
+ if (cycdx == 0)
+ return;
+ /* check that cyclic is still enabled for the specified time */
+ if ( ((float)side * (evaltime - ofs) / cycdx) > cycles )
+ return;
+
+
+ /* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */
+ if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
+ cycyofs = (float)floor((evaltime - ofs) / cycdx);
+ cycyofs *= cycdy;
+ }
+
+ /* calculate where in the cycle we are (overwrite evaltime to reflect this) */
+ evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
+ if (evaltime < ofs) evaltime += cycdx;
+ }
+
+
+ /* store modifiers after (and including ourself) before recalculating curve with new evaltime */
+ mods= fcu->modifiers;
+ fcu->modifiers.first= fcu->modifiers.last= NULL;
+
+ /* re-enter the evaluation loop (but without the burden of evaluating any modifiers, so 'should' be relatively quick) */
+ new_value= evaluate_fcurve(fcu, evaltime);
+
+ /* restore modifiers, and set new value (don't assume everything is still ok after being re-entrant) */
+ fcu->modifiers= mods;
+ *cvalue= new_value + cycyofs;
+}
+
+static FModifierTypeInfo FMI_CYCLES = {
+ FMODIFIER_TYPE_CYCLES, /* type */
+ sizeof(FMod_Cycles), /* size */
+ "Cycles", /* name */
+ "FMod_Cycles", /* struct name */
+ NULL, /* free data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ fcm_cycles_evaluate /* evaluate */
+};
+
+/* Noise F-Curve Modifier --------------------------- */
+
+#if 0 // XXX not yet implemented
+static FModifierTypeInfo FMI_NOISE = {
+ FMODIFIER_TYPE_NOISE, /* type */
+ sizeof(FMod_Noise), /* size */
+ "Noise", /* name */
+ "FMod_Noise", /* struct name */
+ NULL, /* free data */
+ NULL, /* copy data */
+ fcm_noise_new_data, /* new data */
+ fcm_noise_evaluate /* evaluate */
+};
+#endif // XXX not yet implemented
+
+/* Filter F-Curve Modifier --------------------------- */
+
+#if 0 // XXX not yet implemented
+static FModifierTypeInfo FMI_FILTER = {
+ FMODIFIER_TYPE_FILTER, /* type */
+ sizeof(FMod_Filter), /* size */
+ "Filter", /* name */
+ "FMod_Filter", /* struct name */
+ NULL, /* free data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ fcm_filter_evaluate /* evaluate */
+};
+#endif // XXX not yet implemented
+
+
+/* Python F-Curve Modifier --------------------------- */
+
+static void fcm_python_free (FModifier *fcm)
+{
+ FMod_Python *data= (FMod_Python *)fcm->data;
+
+ /* id-properties */
+ IDP_FreeProperty(data->prop);
+ MEM_freeN(data->prop);
+}
+
+static void fcm_python_new_data (void *mdata)
+{
+ FMod_Python *data= (FMod_Python *)mdata;
+
+ /* everything should be set correctly by calloc, except for the prop->type constant.*/
+ data->prop = MEM_callocN(sizeof(IDProperty), "PyFModifierProps");
+ data->prop->type = IDP_GROUP;
+}
+
+static void fcm_python_copy (FModifier *fcm, FModifier *src)
+{
+ FMod_Python *pymod = (FMod_Python *)fcm->data;
+ FMod_Python *opymod = (FMod_Python *)src->data;
+
+ pymod->prop = IDP_CopyProperty(opymod->prop);
+}
+
+static void fcm_python_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+#ifndef DISABLE_PYTHON
+ //FMod_Python *data= (FMod_Python *)fcm->data;
+
+ /* FIXME... need to implement this modifier...
+ * It will need it execute a script using the custom properties
+ */
+#endif /* DISABLE_PYTHON */
+}
+
+static FModifierTypeInfo FMI_PYTHON = {
+ FMODIFIER_TYPE_PYTHON, /* type */
+ sizeof(FMod_Python), /* size */
+ "Python", /* name */
+ "FMod_Python", /* struct name */
+ fcm_python_free, /* free data */
+ fcm_python_copy, /* copy data */
+ fcm_python_new_data, /* new data */
+ fcm_python_evaluate /* evaluate */
+};
+
+
+/* F-Curve Modifier API --------------------------- */
+/* All of the F-Curve Modifier api functions use FModifierTypeInfo structs to carry out
+ * and operations that involve F-Curve modifier specifc code.
+ */
+
+/* These globals only ever get directly accessed in this file */
+static FModifierTypeInfo *fmodifiersTypeInfo[FMODIFIER_NUM_TYPES];
+static short FMI_INIT= 1; /* when non-zero, the list needs to be updated */
+
+/* This function only gets called when FMI_INIT is non-zero */
+static void fmods_init_typeinfo () {
+ fmodifiersTypeInfo[0]= NULL; /* 'Null' F-Curve Modifier */
+ fmodifiersTypeInfo[1]= &FMI_GENERATOR; /* Generator F-Curve Modifier */
+ fmodifiersTypeInfo[2]= &FMI_ENVELOPE; /* Envelope F-Curve Modifier */
+ fmodifiersTypeInfo[3]= &FMI_CYCLES; /* Cycles F-Curve Modifier */
+ fmodifiersTypeInfo[4]= NULL/*&FMI_NOISE*/; /* Apply-Noise F-Curve Modifier */ // XXX unimplemented
+ fmodifiersTypeInfo[5]= NULL/*&FMI_FILTER*/; /* Filter F-Curve Modifier */ // XXX unimplemented
+ fmodifiersTypeInfo[6]= &FMI_PYTHON; /* Custom Python F-Curve Modifier */
+}
+
+/* This function should be used for getting the appropriate type-info when only
+ * a F-Curve modifier type is known
+ */
+FModifierTypeInfo *get_fmodifier_typeinfo (int type)
+{
+ /* initialise the type-info list? */
+ if (FMI_INIT) {
+ fmods_init_typeinfo();
+ FMI_INIT = 0;
+ }
+
+ /* only return for valid types */
+ if ( (type >= FMODIFIER_TYPE_NULL) &&
+ (type <= FMODIFIER_NUM_TYPES ) )
+ {
+ /* there shouldn't be any segfaults here... */
+ return fmodifiersTypeInfo[type];
+ }
+ else {
+ printf("No valid F-Curve Modifier type-info data available. Type = %i \n", type);
+ }
+
+ return NULL;
+}
+
+/* This function should always be used to get the appropriate type-info, as it
+ * has checks which prevent segfaults in some weird cases.
+ */
+FModifierTypeInfo *fmodifier_get_typeinfo (FModifier *fcm)
+{
+ /* only return typeinfo for valid modifiers */
+ if (fcm)
+ return get_fmodifier_typeinfo(fcm->type);
+ else
+ return NULL;
+}
+
+/* API --------------------------- */
+
+/* Add a new F-Curve Modifier to the given F-Curve of a certain type */
+FModifier *fcurve_add_modifier (FCurve *fcu, int type)
+{
+ FModifierTypeInfo *fmi= get_fmodifier_typeinfo(type);
+ FModifier *fcm;
+
+ /* sanity checks */
+ if ELEM(NULL, fcu, fmi)
+ return NULL;
+
+ /* special checks for whether modifier can be added */
+ if ((fcu->modifiers.first) && (type == FMODIFIER_TYPE_CYCLES)) {
+ /* cycles modifier must be first in stack, so for now, don't add if it can't be */
+ // TODO: perhaps there is some better way, but for now,
+ printf("Error: Cannot add 'Cycles' modifier to F-Curve, as 'Cycles' modifier can only be first in stack. \n");
+ return NULL;
+ }
+
+ /* add modifier data */
+ fcm= MEM_callocN(sizeof(FModifier), "F-Curve Modifier");
+ BLI_addtail(&fcu->modifiers, fcm);
+
+ /* init custom settings if necessary */
+ if (fmi->new_data)
+ fmi->new_data(fcm->data);
+
+ /* return modifier for further editing */
+ return fcm;
+}
+
+/* Duplicate all of the F-Curve Modifiers in the Modifier stacks */
+void fcurve_copy_modifiers (ListBase *dst, ListBase *src)
+{
+ FModifier *fcm, *srcfcm;
+
+ if ELEM(NULL, dst, src)
+ return;
+
+ dst->first= dst->last= NULL;
+ BLI_duplicatelist(dst, src);
+
+ for (fcm=dst->first, srcfcm=src->first; fcm && srcfcm; srcfcm=srcfcm->next, fcm=fcm->next) {
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
+
+ /* make a new copy of the F-Modifier's data */
+ fcm->data = MEM_dupallocN(fcm->data);
+
+ /* only do specific constraints if required */
+ if (fmi && fmi->copy_data)
+ fmi->copy_data(fcm, srcfcm);
+ }
+}
+
+/* Remove and free the given F-Curve Modifier from the given F-Curve's stack */
+void fcurve_remove_modifier (FCurve *fcu, FModifier *fcm)
+{
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
+
+ /* sanity checks */
+ if ELEM3(NULL, fcu, fcm, fmi)
+ return;
+
+ /* free modifier's special data */
+ if (fmi->free_data)
+ fmi->free_data(fcm);
+
+ /* remove modifier from stack */
+ BLI_freelinkN(&fcu->modifiers, fcm);
+}
+
+/* Remove all of a given F-Curve's modifiers */
+void fcurve_free_modifiers (FCurve *fcu)
+{
+ FModifier *fcm, *fmn;
+
+ /* sanity check */
+ if (fcu == NULL)
+ return;
+
+ /* free each modifier in order */
+ for (fcm= fcu->modifiers.first; fcm; fcm= fmn) {
+ fmn= fcm->next;
+ fcurve_remove_modifier(fcu, fcm);
+ }
+}
+
+/* Bake modifiers for given F-Curve to curve sample data, in the frame range defined
+ * by start and end (inclusive).
+ */
+void fcurve_bake_modifiers (FCurve *fcu, int start, int end)
+{
+ FPoint *fpt, *new_fpt;
+ int cfra;
+
+ /* sanity checks */
+ // TODO: make these tests report errors using reports not printf's
+ if ELEM(NULL, fcu, fcu->modifiers.first) {
+ printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");
+ return;
+ }
+ if (start >= end) {
+ printf("Error: Frame range for F-Curve Modifier Baking inappropriate \n");
+ return;
+ }
+
+ /* set up sample data */
+ fpt= new_fpt= MEM_callocN(sizeof(FPoint)*(end-start+1), "FPoint FModifier Samples");
+
+ /* sample the curve at 1-frame intervals from start to end frames
+ * - assume that any ChannelDriver possibly present did not interfere in any way
+ */
+ for (cfra= start; cfra <= end; cfra++, fpt++) {
+ fpt->vec[0]= (float)cfra;
+ fpt->vec[1]= evaluate_fcurve(fcu, (float)cfra);
+ }
+
+ /* free any existing sample/keyframe data on curve, and all modifiers */
+ if (fcu->bezt) MEM_freeN(fcu->bezt);
+ if (fcu->fpt) MEM_freeN(fcu->fpt);
+ fcurve_free_modifiers(fcu);
+
+ /* store the samples */
+ fcu->fpt= new_fpt;
+ fcu->totvert= end - start + 1;
+}
+
+/* ***************************** F-Curve - Evaluation ********************************* */
+
+/* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
+ * Note: this is also used for drivers
+ */
+// TODO: set up the modifier system...
+float evaluate_fcurve (FCurve *fcu, float evaltime)
+{
+ FModifier *fcm;
+ float cvalue = 0.0f;
+
+ /* if there is a driver (only if this F-Curve is acting as 'driver'), evaluate it to find value to use as "evaltime"
+ * - this value will also be returned as the value of the 'curve', if there are no keyframes
+ */
+ if (fcu->driver) {
+ /* evaltime now serves as input for the curve */
+ evaltime= cvalue= evaluate_driver(fcu->driver, evaltime);
+ }
+
+ /* evaluate curve-data */
+ if (fcu->bezt)
+ cvalue= fcurve_eval_keyframes(fcu, fcu->bezt, evaltime);
+ else if (fcu->fpt)
+ cvalue= fcurve_eval_samples(fcu, fcu->fpt, evaltime);
+
+ /* evaluate modifiers */
+ for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
+
+ /* only evaluate if there's a callback for this */
+ if (fmi && fmi->evaluate_modifier) {
+ if ((fcm->flag & FMODIFIER_FLAG_DISABLED) == 0)
+ fmi->evaluate_modifier(fcu, fcm, &cvalue, evaltime);
+ }
+ }
+
+ /* return evaluated value */
+ return cvalue;
+}
+
+/* Calculate the value of the given F-Curve at the given frame, and set its curval */
+// TODO: will this be necessary?
+void calculate_fcurve (FCurve *fcu, float ctime)
+{
+ /* calculate and set curval (evaluates driver too) */
+ fcu->curval= evaluate_fcurve(fcu, ctime);
+}
+
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 78b1423e6bc..16d173bf5d6 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -28,6 +28,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#if 0 // XXX old animation system
+
#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -838,6 +840,7 @@ void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
* It is primarily used for patching old files, but is also used in the interface
* to make sure that all segments of the curve use the same interpolation.
*/
+// XXX move to readfile.c for patching old files only..
void set_interpolation_ipocurve (IpoCurve *icu, short ipo)
{
BezTriple *bezt;
@@ -2929,3 +2932,5 @@ float IPO_GetFloatValue (Ipo *ipo, IPO_Channel channel, float ctime)
/* return the value of this channel */
return ctime;
}
+
+#endif // XXX old animation system
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index baf6e4630ee..f06583a6ace 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -36,7 +36,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
@@ -48,7 +47,6 @@
#include "BKE_blender.h"
#include "BKE_curve.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -67,6 +65,11 @@
#define KEY_BPOINT 1
#define KEY_BEZTRIPLE 2
+ // old defines from DNA_ipo_types.h for data-type
+#define IPO_FLOAT 4
+#define IPO_BEZTRIPLE 100
+#define IPO_BPOINT 101
+
int slurph_opt= 1;
@@ -74,8 +77,9 @@ void free_key(Key *key)
{
KeyBlock *kb;
+#if 0 // XXX old animation system
if(key->ipo) key->ipo->id.us--;
-
+#endif // XXX old animation system
while( (kb= key->block.first) ) {
@@ -110,6 +114,7 @@ Key *add_key(ID *id) /* common function */
key->type= KEY_NORMAL;
key->from= id;
+ // XXX the code here uses some defines which will soon be depreceated...
if( GS(id->name)==ID_ME) {
el= key->elemstr;
@@ -150,8 +155,10 @@ Key *copy_key(Key *key)
keyn= copy_libblock(key);
+#if 0 // XXX old animation system
keyn->ipo= copy_ipo(key->ipo);
-
+#endif // XXX old animation system
+
BLI_duplicatelist(&keyn->block, &key->block);
kb= key->block.first;
@@ -179,11 +186,13 @@ void make_local_key(Key *key)
key->id.lib= 0;
new_id(0, (ID *)key, 0);
+
+#if 0 // XXX old animation system
make_local_ipo(key->ipo);
+#endif // XXX old animation system
}
-/*
- * Sort shape keys and Ipo curves after a change. This assumes that at most
+/* Sort shape keys and Ipo curves after a change. This assumes that at most
* one key was moved, which is a valid assumption for the places it's
* currently being called.
*/
@@ -191,30 +200,30 @@ void make_local_key(Key *key)
void sort_keys(Key *key)
{
KeyBlock *kb;
- short i, adrcode;
- IpoCurve *icu = NULL;
+ //short i, adrcode;
+ //IpoCurve *icu = NULL;
KeyBlock *kb2;
/* locate the key which is out of position */
- for( kb= key->block.first; kb; kb= kb->next )
- if( kb->next && kb->pos > kb->next->pos )
+ for (kb= key->block.first; kb; kb= kb->next)
+ if ((kb->next) && (kb->pos > kb->next->pos))
break;
/* if we find a key, move it */
- if( kb ) {
+ if (kb) {
kb = kb->next; /* next key is the out-of-order one */
BLI_remlink(&key->block, kb);
-
+
/* find the right location and insert before */
- for( kb2=key->block.first; kb2; kb2= kb2->next ) {
- if( kb2->pos > kb->pos ) {
+ for (kb2=key->block.first; kb2; kb2= kb2->next) {
+ if (kb2->pos > kb->pos) {
BLI_insertlink(&key->block, kb2->prev, kb);
break;
}
}
-
+
/* if more than one Ipo curve, see if this key had a curve */
-
+#if 0 // XXX old animation system
if(key->ipo && key->ipo->curve.first != key->ipo->curve.last ) {
for(icu= key->ipo->curve.first; icu; icu= icu->next) {
/* if we find the curve, remove it and reinsert in the
@@ -232,13 +241,13 @@ void sort_keys(Key *key)
}
}
}
-
+
/* kb points at the moved key, icu at the moved ipo (if it exists).
* go back now and renumber adrcodes */
/* first new code */
adrcode = kb2->adrcode;
- for( i = kb->adrcode - adrcode; i >= 0; --i, ++adrcode ) {
+ for (i = kb->adrcode - adrcode; i >= 0; i--, adrcode++) {
/* if the next ipo curve matches the current key, renumber it */
if(icu && icu->adrcode == kb->adrcode ) {
icu->adrcode = adrcode;
@@ -248,6 +257,7 @@ void sort_keys(Key *key)
kb->adrcode = adrcode;
kb = kb->next;
}
+#endif // XXX old animation system
}
/* new rule; first key is refkey, this to match drawing channels... */
@@ -1021,11 +1031,13 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
for(a=0; a<me->totvert; a+=step, cfra+= delta) {
- ctime= bsystem_time(scene, 0, cfra, 0.0);
+ ctime= bsystem_time(scene, 0, cfra, 0.0); // xxx ugly cruft!
+#if 0 // XXX old animation system
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
+#endif // XXX old animation system
flag= setkeys(ctime, &me->key->block, k, t, 0);
if(flag==0) {
@@ -1056,13 +1068,15 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
}
}
else {
- ctime= bsystem_time(scene, ob, scene->r.cfra, 0.0);
-
+ ctime= bsystem_time(scene, ob, scene->r.cfra, 0.0); // xxx old cruft
+
+#if 0 // XXX old animation system
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
-
+#endif // XXX old animation system
+
flag= setkeys(ctime, &me->key->block, k, t, 0);
if(flag==0) {
do_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k, t, 0);
@@ -1175,12 +1189,13 @@ static int do_curve_key(Scene *scene, Curve *cu)
cfra= scene->r.cfra;
for(a=0; a<tot; a+=step, cfra+= delta) {
-
- ctime= bsystem_time(scene, 0, cfra, 0.0);
+ ctime= bsystem_time(scene, 0, cfra, 0.0); // XXX old cruft
+#if 0 // XXX old animation system
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
+#endif // XXX old animation system
flag= setkeys(ctime, &cu->key->block, k, t, 0);
if(flag==0) {
@@ -1204,10 +1219,12 @@ static int do_curve_key(Scene *scene, Curve *cu)
do_rel_cu_key(cu, ctime);
}
else {
+#if 0 // XXX old animation system
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
+#endif // XXX old animation system
flag= setkeys(ctime, &cu->key->block, k, t, 0);
@@ -1240,11 +1257,13 @@ static int do_latt_key(Scene *scene, Object *ob, Lattice *lt)
for(a=0; a<tot; a++, cfra+= delta) {
- ctime= bsystem_time(scene, 0, cfra, 0.0);
+ ctime= bsystem_time(scene, 0, cfra, 0.0); // XXX old cruft
+#if 0 // XXX old animation system
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
+#endif // XXX old animation system
flag= setkeys(ctime, &lt->key->block, k, t, 0);
if(flag==0) {
@@ -1273,10 +1292,12 @@ static int do_latt_key(Scene *scene, Object *ob, Lattice *lt)
}
}
else {
+#if 0 // XXX old animation system
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
+#endif // XXX old animation system
flag= setkeys(ctime, &lt->key->block, k, t, 0);
if(flag==0) {
@@ -1338,12 +1359,15 @@ int do_ob_key(Scene *scene, Object *ob)
return 1;
}
else {
+#if 0 // XXX old animation system
+ // NOTE: this stuff was NEVER reliable at all...
if(ob->ipoflag & OB_ACTION_KEY)
do_all_object_actions(scene, ob);
else {
calc_ipo(key->ipo, bsystem_time(scene, ob, scene->r.cfra, 0.0));
execute_ipo((ID *)key, key->ipo);
}
+#endif // XXX old animation system
if(ob->type==OB_MESH) return do_mesh_key(scene, ob, ob->data);
else if(ob->type==OB_CURVE) return do_curve_key(scene, ob->data);
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 134d9f7155a..6e5f7c82aed 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -42,7 +42,6 @@
#include "BLI_arithb.h"
#include "DNA_armature_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -60,7 +59,6 @@
#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -213,7 +211,9 @@ Lattice *copy_lattice(Lattice *lt)
ltn= copy_libblock(lt);
ltn->def= MEM_dupallocN(lt->def);
+#if 0 // XXX old animation system
id_us_plus((ID *)ltn->ipo);
+#endif // XXX old animation system
ltn->key= copy_key(ltn->key);
if(ltn->key) ltn->key->from= (ID *)ltn;
@@ -564,13 +564,16 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
}
+#if 0 // XXX old animation system
/* we want the ipo to work on the default 100 frame range, because there's no
actual time involved in path position */
+ // huh? by WHY!!!!???? - Aligorith
if(cu->ipo) {
fac*= 100.0f;
if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0)
fac/= 100.0;
}
+#endif // XXX old animation system
if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
float q[4], mat[3][3], quat[4];
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 317ec5b4659..fa728f1a951 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -358,7 +358,7 @@ static ID *alloc_libblock_notest(short type)
id = MEM_callocN(sizeof(bArmature), "armature");
break;
case ID_AC:
- id = MEM_callocN(sizeof(bAction), "action");
+ id = MEM_callocN(sizeof(nAction), "action"); // XXX animation system
break;
case ID_NT:
id = MEM_callocN(sizeof(bNodeTree), "nodetree");
@@ -489,7 +489,7 @@ void free_libblock(ListBase *lb, void *idv)
free_camera((Camera*) id);
break;
case ID_IP:
- free_ipo((Ipo *)id);
+ /*free_ipo((Ipo *)id);*/
break;
case ID_KE:
free_key((Key *)id);
@@ -519,7 +519,7 @@ void free_libblock(ListBase *lb, void *idv)
free_armature((bArmature *)id);
break;
case ID_AC:
- free_action((bAction *)id);
+ free_action((nAction *)id); // XXX animation system...
break;
case ID_NT:
ntreeFreeTree((bNodeTree *)id);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index d34bd02cbcd..66339cd977d 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -193,7 +193,9 @@ Material *copy_material(Material *ma)
man= copy_libblock(ma);
+#if 0 // XXX old animation system
id_us_plus((ID *)man->ipo);
+#endif // XXX old animation system
id_us_plus((ID *)man->group);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ae73de892be..9ebf6a5bec3 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -39,13 +39,13 @@
#include "MEM_guardedalloc.h"
+#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_material_types.h"
@@ -68,14 +68,6 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
-#include "BKE_armature.h"
-#include "BKE_action.h"
-#include "BKE_bullet.h"
-#include "BKE_colortools.h"
-#include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_nla.h"
-
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
@@ -85,6 +77,14 @@
#include "BKE_main.h"
#include "BKE_global.h"
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_bullet.h"
+#include "BKE_colortools.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_nla.h"
+#include "BKE_animsys.h"
#include "BKE_anim.h"
#include "BKE_blender.h"
#include "BKE_constraint.h"
@@ -92,7 +92,6 @@
#include "BKE_displist.h"
#include "BKE_group.h"
#include "BKE_icons.h"
-#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -249,8 +248,10 @@ void free_object(Object *ob)
ob->bb= 0;
if(ob->path) free_path(ob->path);
ob->path= 0;
+#if 0 // XXX old animation system
if(ob->ipo) ob->ipo->id.us--;
if(ob->action) ob->action->id.us--;
+#endif // XXX old animation system
if(ob->poselib) ob->poselib->id.us--;
if(ob->dup_group) ob->dup_group->id.us--;
if(ob->defbase.first)
@@ -265,8 +266,9 @@ void free_object(Object *ob)
free_actuators(&ob->actuators);
free_constraints(&ob->constraints);
- free_constraint_channels(&ob->constraintChannels);
+#if 0 // XXX old animation system
free_nlastrips(&ob->nlastrips);
+#endif
#ifndef DISABLE_PYTHON
BPY_free_scriptlink(&ob->scriptlink);
@@ -300,11 +302,10 @@ void unlink_object(Scene *scene, Object *ob)
Scene *sce;
Curve *cu;
Tex *tex;
- Ipo *ipo;
Group *group;
Camera *camera;
bConstraint *con;
- bActionStrip *strip;
+ //bActionStrip *strip; // XXX animsys
ModifierData *md;
int a;
@@ -414,6 +415,7 @@ void unlink_object(Scene *scene, Object *ob)
}
/* strips */
+#if 0 // XXX old animation system
for(strip= obt->nlastrips.first; strip; strip= strip->next) {
if(strip->object==ob)
strip->object= NULL;
@@ -425,6 +427,7 @@ void unlink_object(Scene *scene, Object *ob)
amod->ob= NULL;
}
}
+#endif // XXX old animation system
/* particle systems */
if(obt->particlesystem.first) {
@@ -520,6 +523,8 @@ void unlink_object(Scene *scene, Object *ob)
}
sce= sce->id.next;
}
+
+#if 0 // XXX old animation system
/* ipos */
ipo= G.main->ipo.first;
while(ipo) {
@@ -532,6 +537,7 @@ void unlink_object(Scene *scene, Object *ob)
}
ipo= ipo->id.next;
}
+#endif // XXX old animation system
/* screens */
sc= G.main->screen.first;
@@ -554,6 +560,7 @@ void unlink_object(Scene *scene, Object *ob)
}
}
else if(sl->spacetype==SPACE_IPO) {
+ // XXX animsys this is likely to change...
SpaceIpo *sipo= (SpaceIpo *)sl;
if(sipo->from == (ID *)ob) sipo->from= NULL;
}
@@ -636,7 +643,11 @@ Camera *copy_camera(Camera *cam)
Camera *camn;
camn= copy_libblock(cam);
+
+#if 0 // XXX old animation system
id_us_plus((ID *)camn->ipo);
+#endif // XXX old animation system
+
#ifndef DISABLE_PYTHON
BPY_copy_scriptlink(&camn->scriptlink);
#endif
@@ -783,7 +794,9 @@ Lamp *copy_lamp(Lamp *la)
lan->curfalloff = curvemapping_copy(la->curfalloff);
+#if 0 // XXX old animation system
id_us_plus((ID *)lan->ipo);
+#endif // XXX old animation system
if (la->preview) lan->preview = BKE_previewimg_copy(la->preview);
#ifndef DISABLE_PYTHON
@@ -866,7 +879,10 @@ void free_lamp(Lamp *la)
if(mtex && mtex->tex) mtex->tex->id.us--;
if(mtex) MEM_freeN(mtex);
}
+
+#if 0 // XXX old animation system
la->ipo= 0;
+#endif // XXX old animation system
curvemapping_free(la->curfalloff);
@@ -962,8 +978,12 @@ Object *add_only_object(int type, char *name)
ob->trackflag= OB_POSY;
ob->upflag= OB_POSZ;
}
+
+#if 0 // XXX old animation system
ob->ipoflag = OB_OFFS_OB+OB_OFFS_PARENT;
ob->ipowin= ID_OB; /* the ipowin shown */
+#endif // XXX old animation system
+
ob->dupon= 1; ob->dupoff= 0;
ob->dupsta= 1; ob->dupend= 100;
ob->dupfacesca = 1.0;
@@ -1126,6 +1146,7 @@ static void copy_object_pose(Object *obn, Object *ob)
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
+#if 0 // XXX old animation system
/* note that we can't change lib linked ipo blocks. for making
* proxies this still works correct however because the object
* is changed to object->proxy_from when evaluating the driver. */
@@ -1136,6 +1157,7 @@ static void copy_object_pose(Object *obn, Object *ob)
icu->driver->ob= obn;
}
}
+#endif // XXX old animation system
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
@@ -1192,15 +1214,17 @@ Object *copy_object(Object *ob)
armature_rebuild_pose(obn, obn->data);
}
copy_defgroups(&obn->defbase, &ob->defbase);
+#if 0 // XXX old animation system
copy_nlastrips(&obn->nlastrips, &ob->nlastrips);
- copy_constraints (&obn->constraints, &ob->constraints);
-
- clone_constraint_channels (&obn->constraintChannels, &ob->constraintChannels);
+#endif // XXX old animation system
+ copy_constraints(&obn->constraints, &ob->constraints);
/* increase user numbers */
id_us_plus((ID *)obn->data);
+#if 0 // XXX old animation system
id_us_plus((ID *)obn->ipo);
id_us_plus((ID *)obn->action);
+#endif // XXX old animation system
id_us_plus((ID *)obn->dup_group);
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
@@ -1227,21 +1251,25 @@ Object *copy_object(Object *ob)
void expand_local_object(Object *ob)
{
- bActionStrip *strip;
+ //bActionStrip *strip;
ParticleSystem *psys;
int a;
-
+
+#if 0 // XXX old animation system
id_lib_extern((ID *)ob->action);
id_lib_extern((ID *)ob->ipo);
+#endif // XXX old animation system
id_lib_extern((ID *)ob->data);
id_lib_extern((ID *)ob->dup_group);
for(a=0; a<ob->totcol; a++) {
id_lib_extern((ID *)ob->mat[a]);
}
+#if 0 // XXX old animation system
for (strip=ob->nlastrips.first; strip; strip=strip->next) {
id_lib_extern((ID *)strip->act);
}
+#endif // XXX old animation system
for(psys=ob->particlesystem.first; psys; psys=psys->next)
id_lib_extern((ID *)psys->part);
}
@@ -1363,7 +1391,9 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
ob->parent= target->parent; /* libdata */
Mat4CpyMat4(ob->parentinv, target->parentinv);
+#if 0 // XXX old animation system
ob->ipo= target->ipo; /* libdata */
+#endif // XXX old animation system
/* skip constraints, constraintchannels, nla? */
@@ -1424,6 +1454,7 @@ void disable_speed_curve(int val)
no_speed_curve= val;
}
+// XXX THIS CRUFT NEEDS SERIOUS RECODING ASAP!
/* ob can be NULL */
float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
{
@@ -1435,6 +1466,7 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
/* global time */
cfra*= scene->r.framelen;
+#if 0 // XXX old animation system
if (ob) {
if (no_speed_curve==0 && ob->ipo)
cfra= calc_ipo_time(ob->ipo, cfra);
@@ -1443,6 +1475,7 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0)
cfra-= give_timeoffset(ob);
}
+#endif // XXX old animation system
cfra-= ofs;
@@ -1548,10 +1581,12 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
else if(enable_cu_speed) {
ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0);
+#if 0 // XXX old animation system
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
ctime /= cu->pathlen;
CLAMP(ctime, 0.0, 1.0);
}
+#endif // XXX old animation system
}
else {
ctime= scene->r.cfra - give_timeoffset(ob);
@@ -1766,6 +1801,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4])
}
}
+// XXX what the hell is this?
static int no_parent_ipo=0;
void set_no_parent_ipo(int val)
{
@@ -1795,7 +1831,7 @@ int during_scriptlink(void) {
void where_is_object_time(Scene *scene, Object *ob, float ctime)
{
float *fp1, *fp2, slowmat[4][4] = MAT4_UNITY;
- float stime, fac1, fac2, vec[3];
+ float stime=ctime, fac1, fac2, vec[3];
int a;
int pop;
@@ -1805,6 +1841,7 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
if(ob==NULL) return;
+#if 0 // XXX old animation system
/* this is needed to be able to grab objects with ipos, otherwise it always freezes them */
stime= bsystem_time(scene, ob, ctime, 0.0);
if(stime != ob->ctime) {
@@ -1827,10 +1864,15 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
/* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */
do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1);
}
+#endif // XXX old animation system
+
+ /* execute drivers only, as animation has already been done */
+ BKE_animsys_evaluate_animdata(&ob->id, &ob->adt, ctime, ADT_RECALC_DRIVERS);
if(ob->parent) {
Object *par= ob->parent;
+ // XXX depreceated - animsys
if(ob->ipoflag & OB_OFFS_PARENT) ctime-= give_timeoffset(ob);
/* hurms, code below conflicts with depgraph... (ton) */
@@ -2019,7 +2061,7 @@ void where_is_object_simul(Scene *scene, Object *ob)
for a lamp that is the child of another object */
{
Object *par;
- Ipo *ipo;
+ //Ipo *ipo;
float *fp1, *fp2;
float slowmat[4][4];
float fac1, fac2;
@@ -2028,8 +2070,9 @@ for a lamp that is the child of another object */
/* NO TIMEOFFS */
/* no ipo! (because of dloc and realtime-ipos) */
- ipo= ob->ipo;
- ob->ipo= NULL;
+ // XXX old animation system
+ //ipo= ob->ipo;
+ //ob->ipo= NULL;
if(ob->parent) {
par= ob->parent;
@@ -2065,7 +2108,8 @@ for a lamp that is the child of another object */
}
/* WATCH IT!!! */
- ob->ipo= ipo;
+ // XXX old animation system
+ //ob->ipo= ipo;
}
/* for calculation of the inverse parent transform, only used for editor */
@@ -2287,14 +2331,22 @@ void object_handle_update(Scene *scene, Object *ob)
lattice_calc_modifiers(scene, ob);
}
else if(ob->type==OB_CAMERA) {
- Camera *cam = (Camera *)ob->data;
- calc_ipo(cam->ipo, frame_to_float(scene, scene->r.cfra));
- execute_ipo(&cam->id, cam->ipo);
+ //Camera *cam = (Camera *)ob->data;
+
+ // xxx old animation code here
+ //calc_ipo(cam->ipo, frame_to_float(scene, scene->r.cfra));
+ //execute_ipo(&cam->id, cam->ipo);
+
+ // in new system, this has already been done! - aligorith
}
else if(ob->type==OB_LAMP) {
- Lamp *la = (Lamp *)ob->data;
- calc_ipo(la->ipo, frame_to_float(scene, scene->r.cfra));
- execute_ipo(&la->id, la->ipo);
+ //Lamp *la = (Lamp *)ob->data;
+
+ // xxx old animation code here
+ //calc_ipo(la->ipo, frame_to_float(scene, scene->r.cfra));
+ //execute_ipo(&la->id, la->ipo);
+
+ // in new system, this has already been done! - aligorith
}
else if(ob->type==OB_ARMATURE) {
/* this happens for reading old files and to match library armatures with poses */
@@ -2306,7 +2358,7 @@ void object_handle_update(Scene *scene, Object *ob)
// printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
}
else {
- do_all_pose_actions(scene, ob);
+ //do_all_pose_actions(scene, ob); // xxx old animation system
where_is_pose(scene, ob);
}
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 9e8651d9847..6b8f7bfecc7 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -46,7 +46,7 @@
#include "DNA_object_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
-#include "DNA_ipo_types.h"
+#include "DNA_ipo_types.h" // XXX old animation system stuff to remove!
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -65,7 +65,6 @@
#include "BKE_displist.h"
#include "BKE_particle.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_ipo.h"
#include "BKE_object.h"
#include "BKE_softbody.h"
#include "BKE_material.h"
@@ -1922,10 +1921,12 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
}
/* set correct ipo timing */
+#if 0 // XXX old animation system
if(part->flag&PART_ABS_TIME && part->ipo){
calc_ipo(part->ipo, cfra);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
return 1;
}
@@ -2040,11 +2041,13 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
keys->steps = ctx->steps;
/* correct child ipo timing */
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
float dsta=part->end-part->sta;
calc_ipo(part->ipo, 100.0f*(ctx->cfra-(part->sta+dsta*cpa->rand[1]))/(part->lifetime*(1.0f - part->randlife*cpa->rand[0])));
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
/* get different child parameters from textures & vgroups */
ptex.length=part->length*(1.0f - part->randlength*cpa->rand[0]);
@@ -2922,7 +2925,9 @@ static void default_particle_settings(ParticleSettings *part)
part->boidfac[i]=0.5;
}
+#if 0 // XXX old animation system
part->ipo = NULL;
+#endif // XXX old animation system
part->simplify_refsize= 1920;
part->simplify_rate= 1.0f;
@@ -3257,10 +3262,12 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd,
size=ptex.size;
}
+#if 0 // XXX old animation system
if(icu_size){
calc_icu(icu_size,pa->time);
size*=icu_size->curval;
}
+#endif // XXX old animation system
if(vg_size)
size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size);
@@ -3298,6 +3305,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
if(part->childtype==PART_CHILD_FACES){
size=part->size;
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
IpoCurve *icu;
@@ -3314,6 +3322,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
size = icu->curval;
}
}
+#endif // XXX old animation system
}
else
size=psys->particles[cpa->parent].size;
@@ -3536,11 +3545,13 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
}
/* correct child ipo timing */
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
calc_ipo(part->ipo, 100.0f*t);
execute_ipo((ID *)part, part->ipo);
}
-
+#endif // XXX old animation system
+
/* get different child parameters from textures & vgroups */
ptex.clump=1.0;
ptex.kink=1.0;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 20826b6e268..2dea71856e9 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -42,11 +42,11 @@
#include "DNA_object_force.h"
#include "DNA_object_types.h"
#include "DNA_material_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
+#include "DNA_ipo_types.h" // XXX old animation system stuff... to be removed!
#include "BLI_rand.h"
#include "BLI_jitter.h"
@@ -68,7 +68,6 @@
#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
#include "BKE_material.h"
-#include "BKE_ipo.h"
#include "BKE_softbody.h"
#include "BKE_depsgraph.h"
#include "BKE_lattice.h"
@@ -1528,7 +1527,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
ParticleSettings *part;
ParticleTexture ptex;
Material *ma=0;
- IpoCurve *icu=0;
+ //IpoCurve *icu=0; // XXX old animation system
int totpart;
float rand,length;
@@ -1569,11 +1568,13 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
pa->lifetime=100.0f;
}
else{
+#if 0 // XXX old animation system
icu=find_ipocurve(psys->part->ipo,PART_EMIT_LIFE);
if(icu){
calc_icu(icu,100*ptex.time);
pa->lifetime*=icu->curval;
}
+#endif // XXX old animation system
/* need to get every rand even if we don't use them so that randoms don't affect eachother */
rand= BLI_frand();
@@ -1626,7 +1627,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
}
static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
{
- IpoCurve *icu=0;
+ //IpoCurve *icu=0; // XXX old animation system
ParticleData *pa;
int p, totpart=psys->totpart;
@@ -1634,6 +1635,7 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
initialize_particle(pa,p,ob,psys,psmd);
if(psys->part->type != PART_FLUID) {
+#if 0 // XXX old animation system
icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ);
if(icu){
float time=psys->part->sta, end=psys->part->end;
@@ -1642,6 +1644,7 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
p=0;
pa=psys->particles;
+
calc_icu(icu,time);
v1=icu->curval;
if(v1<0.0f) v1=0.0f;
@@ -1682,6 +1685,7 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
pa->flag |= PARS_UNEXIST;
}
}
+#endif // XXX old animation system
}
}
/* sets particle to the emitter surface with initial velocity & rotation */
@@ -1691,7 +1695,7 @@ static void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys,
ParticleSettings *part;
ParticleTexture ptex;
ParticleKey state;
- IpoCurve *icu=0;
+ //IpoCurve *icu=0; // XXX old animation system
float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
@@ -1834,11 +1838,13 @@ static void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys,
if(part->partfac!=0.0)
VECADDFAC(vel,vel,p_vel,part->partfac);
+#if 0 // XXX old animation system
icu=find_ipocurve(psys->part->ipo,PART_EMIT_VEL);
if(icu){
calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
ptex.ivel*=icu->curval;
}
+#endif // XXX old animation system
VecMulf(vel,ptex.ivel);
@@ -1908,11 +1914,13 @@ static void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys,
Normalize(pa->state.ave);
VecMulf(pa->state.ave,part->avefac);
+#if 0 // XXX old animation system
icu=find_ipocurve(psys->part->ipo,PART_EMIT_AVE);
if(icu){
calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
VecMulf(pa->state.ave,icu->curval);
}
+#endif // XXX old animation system
}
pa->dietime = pa->time + pa->lifetime;
@@ -3928,12 +3936,12 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
ParticleSettings *part=psys->part;
KDTree *tree=0;
BoidVecFunc bvf;
- IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE);
+ IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
Material *ma=give_current_material(ob,part->omat);
float timestep;
int p, totpart;
/* current time */
- float ctime, ipotime;
+ float ctime, ipotime; // XXX old animation system
/* frame & time changes */
float dfra, dtime, pa_dtime, pa_dfra=0.0;
float birthtime, dietime;
@@ -3946,12 +3954,14 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
timestep=psys_get_timestep(part);
dtime= dfra*timestep;
ctime= cfra*timestep;
- ipotime= cfra;
+ ipotime= cfra; // XXX old animation system
+#if 0 // XXX old animation system
if(part->flag&PART_ABS_TIME && part->ipo){
calc_ipo(part->ipo, cfra);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
if(dfra<0.0){
float *vg_size=0;
@@ -3962,11 +3972,13 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
if(pa->flag & PARS_UNEXIST) continue;
/* set correct ipo timing */
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
calc_ipo(part->ipo, ipotime);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
@@ -4024,11 +4036,13 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
copy_particle_key(&pa->prev_state,&pa->state,1);
/* set correct ipo timing */
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
calc_ipo(part->ipo, ipotime);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
/* reactions can change birth time so they need to be checked first */
@@ -4198,7 +4212,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
ParticleSettings *part=psys->part;
ParticleData *pa;
ParticleKey state;
- IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE);
+ IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
Material *ma=give_current_material(ob,part->omat);
int p;
float ipotime=cfra, disp, birthtime, dietime, *vg_size= NULL;
@@ -4218,11 +4232,13 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
calc_ipo(part->ipo, ipotime);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
pa->size= psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
psys->lattice= psys_get_lattice(scene, ob, psys);
@@ -4437,10 +4453,12 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
BKE_ptcache_id_time(&pid, scene, 0.0f, &startframe, &endframe, NULL);
/* update ipo's */
+#if 0 // XXX old animation system
if((part->flag & PART_ABS_TIME) && part->ipo) {
calc_ipo(part->ipo, cfra);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
/* hair if it's already done is handled separate */
if(part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)) {
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 059aeadb24f..9c74014853d 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -404,7 +404,8 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
*startframe= cache->startframe;
*endframe= cache->endframe;
- if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0) {
+ // XXX ipoflag is depreceated - old animation system stuff
+ if (/*(ob->ipoflag & OB_OFFS_PARENT) &&*/ (ob->partype & PARSLOW)==0) {
offset= give_timeoffset(ob);
*startframe += (int)(offset+0.5f);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index efd27342aed..8fbbe83373e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -43,6 +43,7 @@
#endif
#include "MEM_guardedalloc.h"
+#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_color_types.h"
#include "DNA_constraint_types.h"
@@ -59,6 +60,7 @@
#include "BKE_action.h"
#include "BKE_anim.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_colortools.h"
#include "BKE_colortools.h"
@@ -577,22 +579,54 @@ static void scene_update(Scene *sce, unsigned int lay)
object_handle_update(sce, ob); // bke_object.h
/* only update layer when an ipo */
- if(ob->ipo && has_ipo_code(ob->ipo, OB_LAY) ) {
- base->lay= ob->lay;
- }
+ // XXX old animation system
+ //if(ob->ipo && has_ipo_code(ob->ipo, OB_LAY) ) {
+ // base->lay= ob->lay;
+ //}
}
}
+/* This (evil) function is needed to cope with two legacy Blender rendering features
+ * mblur (motion blur that renders 'subframes' and blurs them together), and fields
+ * rendering. Thus, the use of ugly globals from object.c
+ */
+// BAD... EVIL... JUJU...!!!!
+// XXX moved here temporarily
+float frame_to_float (Scene *scene, int cfra) /* see also bsystem_time in object.c */
+{
+ extern float bluroffs; /* bad stuff borrowed from object.c */
+ extern float fieldoffs;
+ float ctime;
+
+ ctime= (float)cfra;
+ ctime+= bluroffs+fieldoffs;
+ ctime*= scene->r.framelen;
+
+ return ctime;
+}
+
/* applies changes right away, does all sets too */
void scene_update_for_newframe(Scene *sce, unsigned int lay)
{
Scene *scene= sce;
+ float ctime = frame_to_float(sce, sce->r.cfra);
/* clears all BONE_UNKEYED flags for every pose's pchans */
- framechange_poses_clear_unkeyed();
+ // xxx old animation system
+ //framechange_poses_clear_unkeyed();
+
+ /* clear animation overrides */
+ // XXX TODO...
+
+ /* All 'standard' (i.e. without any dependencies) animation is handled here,
+ * with an 'local' to 'macro' order of evaluation. This should ensure that
+ * settings stored nestled within a hierarchy (i.e. settings in a Texture block
+ * can be overridden by settings from Scene, which owns the Texture through a hierarchy
+ * such as Scene->World->MTex/Texture) can still get correctly overridden.
+ */
+ BKE_animsys_evaluate_all_animation(G.main, ctime);
+
- /* object ipos are calculated in where_is_object */
- do_all_data_ipos(sce);
#ifndef DISABLE_PYTHON
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED, 0);
#endif
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 9036156d6b6..01effda2e30 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -41,7 +41,6 @@
#include "BLI_arithb.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
#include "BKE_plugin_types.h"
#include "BKE_sequence.h"
#include "BKE_texture.h"
@@ -2776,7 +2775,7 @@ static void store_icu_yrange_speed(struct Sequence * seq,
void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
{
float facf0 = seq->facf0;
- float ctime, div;
+ //float ctime, div;
int cfra;
float fallback_fac;
SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
@@ -2801,8 +2800,8 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
/* if there is no IPO, try to make retiming easy by stretching the
strip */
-
- if (!seq->ipo && seq->seq1 && seq->seq1->enddisp != seq->seq1->start
+ // XXX old animation system - seq
+ if (/*!seq->ipo &&*/ seq->seq1 && seq->seq1->enddisp != seq->seq1->start
&& seq->seq1->len != 0) {
fallback_fac = (float) seq->seq1->len /
(float) (seq->seq1->enddisp - seq->seq1->start);
@@ -2825,6 +2824,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
v->lastValidFrame = 0;
for (cfra = 1; cfra < v->length; cfra++) {
+#if 0 // XXX old animation system
if(seq->ipo) {
if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
ctime = frame_to_float(scene, seq->startdisp + cfra);
@@ -2837,7 +2837,9 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
calc_ipo(seq->ipo, ctime/div);
execute_ipo((ID *)seq, seq->ipo);
- } else {
+ } else
+#endif // XXX old animation system
+ {
seq->facf0 = fallback_fac;
}
seq->facf0 *= v->globalSpeed;
@@ -2854,6 +2856,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
} else {
v->lastValidFrame = 0;
for (cfra = 0; cfra < v->length; cfra++) {
+#if 0 // XXX old animation system
if(seq->ipo) {
if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
ctime = frame_to_float(scene, seq->startdisp + cfra);
@@ -2867,11 +2870,12 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
calc_ipo(seq->ipo, ctime/div);
execute_ipo((ID *)seq, seq->ipo);
}
+#endif // XXX old animation system
if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
seq->facf0 *= v->length;
}
- if (!seq->ipo) {
+ if (/*!seq->ipo*/ 1) { // XXX old animation system - seq
seq->facf0 = (float) cfra * fallback_fac;
}
seq->facf0 *= v->globalSpeed;
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index 5cc087e857e..9fd924f7e7a 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -33,14 +33,12 @@
#include "MEM_guardedalloc.h"
-#include "DNA_ipo_types.h"
#include "DNA_listBase.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "BKE_global.h"
#include "BKE_image.h"
-#include "BKE_ipo.h"
#include "BKE_main.h"
#include "BKE_sequence.h"
#include "BKE_utildefines.h"
@@ -790,11 +788,14 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
return;
}
+#if 0 // XXX old animation system
if(seq->ipo && seq->ipo->curve.first) {
do_seq_ipo(scene, seq, cfra);
fac= seq->facf0;
facf= seq->facf1;
- } else {
+ } else
+#endif // XXX old animation system
+ {
sh.get_default_fac(seq, cfra, &fac, &facf);
}
@@ -956,8 +957,8 @@ TStripElem *give_tstripelem(Sequence *seq, int cfra)
alpha over mode...
*/
if (seq->blend_mode != SEQ_BLEND_REPLACE ||
- (seq->ipo && seq->ipo->curve.first && (
- !(seq->type & SEQ_EFFECT) || !seq->seq1))) {
+ (/*seq->ipo && seq->ipo->curve.first &&*/
+ (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
Strip * s = seq->strip;
if (cfra < seq->start) {
se = s->tstripdata_startstill;
@@ -1503,10 +1504,12 @@ static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se
mul = seq->mul;
if(seq->blend_mode == SEQ_BLEND_REPLACE) {
+#if 0 // XXX old animation system
if (seq->ipo && seq->ipo->curve.first) {
do_seq_ipo(scene, seq, cfra);
mul *= seq->facf0;
}
+#endif // XXX old animation system
mul *= seq->blend_opacity / 100.0;
}
@@ -1591,10 +1594,12 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
mul = seq->mul;
if(seq->blend_mode == SEQ_BLEND_REPLACE) {
+#if 0 // XXX old animation system
if (seq->ipo && seq->ipo->curve.first) {
do_seq_ipo(scene, seq, cfra);
mul *= seq->facf0;
}
+#endif // XXX old animation system
mul *= seq->blend_opacity / 100.0;
}
@@ -1988,11 +1993,14 @@ static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *s
se->se2 = 0;
se->se3 = 0;
+#if 0 // XXX old animation system
if(seq->ipo && seq->ipo->curve.first) {
do_seq_ipo(scene, seq, cfra);
fac= seq->facf0;
facf= seq->facf1;
- } else {
+ } else
+#endif // XXX old animation system
+ {
sh.get_default_fac(seq, cfra, &fac, &facf);
}
@@ -2248,9 +2256,11 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
seq->facf0 = seq->facf1 = 1.0;
+#if 0 // XXX old animation system
if(seq->ipo && seq->ipo->curve.first) {
do_seq_ipo(scene, seq, cfra);
}
+#endif
if( scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 70ced6e59d6..495d50725d0 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -72,7 +72,6 @@
#include "BKE_texture.h"
#include "BKE_key.h"
#include "BKE_icons.h"
-#include "BKE_ipo.h"
#include "BKE_brush.h"
#include "BKE_node.h"
@@ -570,7 +569,9 @@ Tex *copy_texture(Tex *tex)
if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima);
else texn->ima= 0;
+#if 0 // XXX old animation system
id_us_plus((ID *)texn->ipo);
+#endif // XXX old animation system
if(texn->plugin) {
texn->plugin= MEM_dupallocN(texn->plugin);
@@ -888,13 +889,17 @@ int BKE_texture_dependsOnTime(const struct Tex *texture)
if(texture->plugin) {
// assume all plugins depend on time
return 1;
- } else if( texture->ima &&
+ }
+ else if( texture->ima &&
ELEM(texture->ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
return 1;
- } else if(texture->ipo) {
+ }
+#if 0 // XXX old animation system
+ else if(texture->ipo) {
// assume any ipo means the texture is animated
return 1;
}
+#endif // XXX old animation system
return 0;
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index bef372e39f1..bd747bc1b61 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -76,7 +76,10 @@ void free_world(World *wrld)
}
BKE_previewimg_free(&wrld->preview);
+#if 0 // XXX old animation system
wrld->ipo= 0;
+#endif // XXX old animation system
+
BKE_icon_delete((struct ID*)wrld);
wrld->id.icon_id = 0;
}
@@ -129,7 +132,10 @@ World *copy_world(World *wrld)
#ifndef DISABLE_PYTHON
BPY_copy_scriptlink(&wrld->scriptlink);
#endif
+
+#if 0 // XXX old animation system
id_us_plus((ID *)wrldn->ipo);
+#endif // XXX old animation system
return wrldn;
}