2.5: Blender "Animato" - New Animation System
authorJoshua Leung <aligorith@gmail.com>
Sat, 17 Jan 2009 03:12:50 +0000 (03:12 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sat, 17 Jan 2009 03:12:50 +0000 (03:12 +0000)
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!).

68 files changed:
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_animsys.h [new file with mode: 0644]
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/BKE_fcurve.h [new file with mode: 0644]
source/blender/blenkernel/BKE_ipo.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c [new file with mode: 0644]
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/fcurve.c [new file with mode: 0644]
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/sequence.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/world.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/anim_ops.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/animation/keyframes_general.c
source/blender/editors/animation/keyframing.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/poselib.c
source/blender/editors/armature/poseobject.c
source/blender/editors/curve/editcurve.c
source/blender/editors/gpencil/editaction_gpencil.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_keyframes_edit.h
source/blender/editors/include/ED_keyframing.h
source/blender/editors/object/editconstraint.c
source/blender/editors/object/editkey.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_ops.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_ops.c
source/blender/editors/space_action/action_select.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/makesdna/DNA_anim_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_camera_types.h
source/blender/makesdna/DNA_ipo_types.h
source/blender/makesdna/DNA_key_types.h
source/blender/makesdna/DNA_lamp_types.h
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/initrender.c
source/blender/render/intern/source/texture.c
source/blender/windowmanager/intern/wm_files.c

index 11e2b828436e051192ac8898669f7d6bfb0175f7..444a97364abc6a28ab185ff7d5a87cbc753fc92a 100644 (file)
@@ -26,6 +26,7 @@
  * All rights reserved.
  *
  * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
+ *                             Full recode, Joshua Leung, 2009
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 #include "DNA_listBase.h"
 
 /**
- * The following structures are defined in DNA_action_types.h
+ * The following structures are defined in DNA_action_types.h, and DNA_anim_types.h
  */
 
-struct bAction;
-struct bActionChannel;
+struct nAction;
 struct bPose;
 struct bPoseChannel;
 struct Object;
@@ -52,7 +52,23 @@ struct ID;
 extern "C" {
 #endif
 
-struct bAction *add_empty_action(const char name[]);
+struct nAction *add_empty_action(const char name[]);
+       
+       /**
+ * Allocate a new bAction on the heap and copy 
+ * the contents of src into it. If src is NULL NULL is returned.
+ */
+
+struct nAction *copy_action(struct nAction *src);
+
+/**
+ * Deallocate the action's channels including constraint channels.
+ * does not free the action structure.
+ */
+void free_action(struct nAction *act);
+
+// XXX is this needed?
+void make_local_action(struct nAction *act);
        
 /**
  * Removes and deallocates all channels from a pose.
@@ -72,18 +88,6 @@ void free_pose(struct bPose *pose);
 void copy_pose(struct bPose **dst, struct bPose *src,
                           int copyconstraints);
 
-/**
- * Deallocate the action's channels including constraint channels.
- * does not free the action structure.
- */
-void free_action(struct bAction * id);
-
-void make_local_action(struct bAction *act);
-
-/* only for armatures, doing pose actions only too */
-void do_all_pose_actions(struct Scene *scene, struct Object *);
-/* only for objects, doing only 1 channel */
-void do_all_object_actions(struct Scene *scene, struct Object *);
 
 
 /**
@@ -113,13 +117,6 @@ void update_pose_constraint_flags(struct bPose *pose);
 /* clears BONE_UNKEYED flags for frame changing */
 void framechange_poses_clear_unkeyed(void);
 
-/**
- * Allocate a new bAction on the heap and copy 
- * the contents of src into it. If src is NULL NULL is returned.
- */
-
-struct bAction *copy_action(struct bAction *src);
-
 /**
  * Some kind of bounding box operation on the action.
  */
@@ -135,22 +132,6 @@ void extract_pose_from_action(struct bPose *pose, struct bAction *act, float cti
  */
 void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bAction *act, float cframe);
 
-/**
- * Iterate through the action channels of the action
- * and return the channel with the given name.
- * Returns NULL if no channel.
- */
-struct bActionChannel *get_action_channel(struct bAction *act,  const char *name);
-/**
- * Iterate through the action channels of the action
- * and return the channel with the given name.
- * Returns and adds new channel if no channel.
- */
-struct bActionChannel *verify_action_channel(struct bAction *act, const char *name);
-
-  /* baking */
-struct bAction *bake_obIPO_to_action(struct Object *ob);
-
 /* exported for game engine */
 void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
 void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
@@ -164,10 +145,7 @@ void rest_pose(struct bPose *pose);
 float get_action_frame(struct Object *ob, float cframe);
 /* map strip time to global time (frame nr)  */
 float get_action_frame_inv(struct Object *ob, float cframe);
-/* builds a list of NlaIpoChannel with ipo values to write in datablock */
-void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, const char *name, float ctime);
-/* write values returned by extract_ipochannels_from_action, returns the number of value written */
-int execute_ipochannels(ListBase *lb);
+
 
 /* functions used by the game engine */
 void game_copy_pose(struct bPose **dst, struct bPose *src);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
new file mode 100644 (file)
index 0000000..bdb39cd
--- /dev/null
@@ -0,0 +1,34 @@
+/* Testing code for new animation system in 2.5 
+ * Copyright 2009, Joshua Leung
+ */
+
+#ifndef BKE_ANIM_SYS_H
+#define BKE_ANIM_SYS_H
+
+struct ID;
+struct ListBase;
+struct Main;
+struct AnimData;
+
+/* ************************************* */
+/* AnimData API */
+
+/* Get AnimData from the given ID-block. */
+struct AnimData *BKE_animdata_from_id(struct ID *id);
+
+/* ************************************* */
+// TODO: overrides, remapping, and path-finding api's
+
+/* ************************************* */
+/* Evaluation API */
+
+/* Evaluation loop for evaluating animation data  */
+void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, float ctime, short recalc);
+
+/* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only */
+void BKE_animsys_evaluate_all_animation(struct Main *main, float ctime);
+
+
+/* ************************************* */
+
+#endif /* BKE_ANIM_SYS_H*/
index 043062a2871cceb3d43b88a324408d455a703fbc..0d8c81a5a7574618803d4c67b350475676db4e6a 100644 (file)
@@ -35,7 +35,6 @@ struct bConstraintTarget;
 struct ListBase;
 struct Object;
 struct Scene;
-struct bConstraintChannel;
 struct bPoseChannel;
 
 /* ---------------------------------------------------------------------------- */
@@ -120,15 +119,6 @@ void free_constraint_data(struct bConstraint *con);
 void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
 short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
 
-/* Constraint Channel function prototypes */
-struct bConstraintChannel *get_constraint_channel(struct ListBase *list, const char *name);
-struct bConstraintChannel *verify_constraint_channel(struct ListBase *list, const char *name);
-void do_constraint_channels(struct ListBase *conbase, struct ListBase *chanbase, float ctime, short onlydrivers);
-void copy_constraint_channels(struct ListBase *dst, struct ListBase *src);
-void clone_constraint_channels(struct ListBase *dst, struct ListBase *src);
-void free_constraint_channels(struct ListBase *chanbase);
-
-
 /* Constraint Evaluation function prototypes */
 struct bConstraintOb *constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
 void constraints_clear_evalob(struct bConstraintOb *cob);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
new file mode 100644 (file)
index 0000000..82914cb
--- /dev/null
@@ -0,0 +1,100 @@
+/* Testing code for new animation system in 2.5 
+ * Copyright 2009, Joshua Leung
+ */
+
+#ifndef BKE_FCURVE_H
+#define BKE_FCURVE_H
+
+//struct ListBase;
+struct FCurve;
+struct FModifier;
+struct ChannelDriver;
+struct BezTriple;
+
+/* ************** Keyframe Tools ***************** */
+
+// XXX this stuff is defined in BKE_ipo.h too, so maybe skip for now?
+typedef struct CfraElem {
+       struct CfraElem *next, *prev;
+       float cfra;
+       int sel;
+} CfraElem;
+
+void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
+
+/* ************** F-Curve Drivers ***************** */
+
+void fcurve_free_driver(struct FCurve *fcu);
+
+/* ************** F-Curve Modifiers *************** */
+
+/* F-Curve Modifier Type-Info (fmi):
+ *  This struct provides function pointers for runtime, so that functions can be
+ *  written more generally (with fewer/no special exceptions for various modifiers).
+ *
+ *  Callers of these functions must check that they actually point to something useful,
+ *  as some constraints don't define some of these.
+ *
+ *  Warning: it is not too advisable to reorder order of members of this struct,
+ *                     as you'll have to edit quite a few ($FMODIFIER_NUM_TYPES) of these
+ *                     structs.
+ */
+typedef struct FModifierTypeInfo {
+       /* admin/ident */
+       short type;                             /* FMODIFIER_TYPE_### */
+       short size;                             /* size in bytes of the struct */
+       char name[32];                  /* name of modifier in interface */
+       char structName[32];    /* name of struct for SDNA */
+       
+       /* data management function pointers - special handling */
+               /* free any data that is allocated separately (optional) */
+       void (*free_data)(struct FModifier *fcm);
+               /* copy any special data that is allocated separately (optional) */
+       void (*copy_data)(struct FModifier *fcm, struct FModifier *src);
+               /* set settings for data that will be used for FCuModifier.data (memory already allocated using MEM_callocN) */
+       void (*new_data)(void *mdata);
+       
+       /* evaluation */
+               /* evaluate the modifier for the given time and 'accumulated' value */
+       void (*evaluate_modifier)(struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime);
+} FModifierTypeInfo;
+
+/* Function Prototypes for FModifierTypeInfo's */
+FModifierTypeInfo *fmodifier_get_typeinfo(struct FModifier *fcm);
+FModifierTypeInfo *get_fmodifier_typeinfo(int type);
+
+/* ---------------------- */
+
+// TODO... general API here..
+struct FModifier *fcurve_add_modifier(struct FCurve *fcu, int type);
+void fcurve_copy_modifiers(ListBase *dst, ListBase *src);
+void fcurve_remove_modifier(struct FCurve *fcu, struct FModifier *fcm);
+void fcurve_free_modifiers(struct FCurve *fcu);
+void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
+
+/* ************** F-Curves API ******************** */
+
+/* -------- Data Managemnt  --------  */
+
+void free_fcurve(struct FCurve *fcu);
+struct FCurve *copy_fcurve(struct FCurve *fcu);
+
+/* find matching F-Curve in the given list of F-Curves */
+struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
+
+/* -------- Curve Sanity --------  */
+
+void calchandles_fcurve(struct FCurve *fcu);
+void testhandles_fcurve(struct FCurve *fcu);
+void sort_time_fcurve(struct FCurve *fcu);
+short test_time_fcurve(struct FCurve *fcu);
+
+/* -------- Evaluation --------  */
+
+/* evaluate fcurve */
+float evaluate_fcurve(struct FCurve *fcu, float evaltime);
+/* evaluate fcurve and store value */
+void calculate_fcurve(struct FCurve *fcu, float ctime);
+
+
+#endif /* BKE_FCURVE_H*/
index 21e80708113d00236a8fdf585618db144acde5c4..845ff9bbb77a9ac6d28c7dd6aa3dc2e167466bf7 100644 (file)
@@ -35,6 +35,8 @@
 extern "C" {
 #endif
 
+#if 0 // XXX old animation system
+
 typedef struct CfraElem {
        struct CfraElem *next, *prev;
        float cfra;
@@ -145,6 +147,8 @@ void clear_delta_obipo(struct Ipo *ipo);
 short IPO_GetChannels(struct Ipo *ipo, short *channels);
 float IPO_GetFloatValue(struct Ipo *ipo, short c, float ctime);
 
+#endif // XXX old animation system
+
 #ifdef __cplusplus
 };
 #endif
index 06597c983cad0fb3001b58884b7274f1cfae52b9..d468daef52a6720e5d41a1e54f932ad66a0d1957 100644 (file)
 
 #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"
 
 /* ***************** 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)
index 6a6d8c46f9e0c9f11a5368a847211b73be477c94..e9d0fc7c95a6ae8bf9080452a2bf5818a1afbf35 100644 (file)
@@ -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 (file)
index 0000000..d377ce0
--- /dev/null
@@ -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);
+       }
+}
+
+/* ***************************************** */ 
index 65225471d0f519c8fbb7f9b0b0a9dacceef55a2e..d256e8dc8e75ddb239eeeb92312c0d75b7a95ef9 100644 (file)
@@ -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]);
                
index f83428766f92282f6278480319a23c931bf9dd8d..f5613a347000fb556f455d3a8da9a4835e395e6f 100644 (file)
 #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;
                
index 4fba2c3d7468c267365e54b9c91b88a802ea302e..d52d91e40e91fac30de54ec05ddf9cb721873d9d 100644 (file)
@@ -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];
index 01dd6c0c6578b1391f5d8d2535e75307e3335f4f..4567717ea7ab085d5f265f5393f45c7a8a0ae497 100644 (file)
@@ -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 (file)
index 0000000..0e94faf
--- /dev/null
@@ -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);
+}
+
index 78b1423e6bc24a24ad0b92e6e86a2421c82a1dea..16d173bf5d6f10081d4597bad32a0850cb572679 100644 (file)
@@ -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
index baf6e4630eea9ed4aac58a564dd4566a5a010b0a..f06583a6aceb6c649d59b1f10fd64142c10238db 100644 (file)
@@ -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"
 #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);
index 134d9f7155a4345837b05d4d5701571949c46993..6e5f7c82aed0b68fa2cafa760877533a402573cd 100644 (file)
@@ -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];
index 317ec5b4659841e3e8ef7e806593bc69a39956b5..fa728f1a951c565ef2a1e26909b941ddd1e2cb2a 100644 (file)
@@ -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);
index d34bd02cbcd8b3cc3b3ae7e2fe0280248eb7a2db..66339cd977d2a91d6368ff391f28c0a3b9b6d0f4 100644 (file)
@@ -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);
        
        
index ae73de892be96b1749d78a5f70dcf1bb006b354c..9ebf6a5bec396df68213d02c697281beeabe55c3 100644 (file)
 
 #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"
 #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"
 #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);
                                }
                        }
index 9e8651d98476ee6846d294477505b0b3c35af484..6b8f7bfecc7c74d77c98c57d0d2df9575dd5ee20 100644 (file)
@@ -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;
index 20826b6e268c054c381461b38272d502b88ced68..2dea71856e9514bb956a0be6f781412c18295664 100644 (file)
 #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)) {
index 059aeadb24f31f587876544c969dfe67682f17cc..9c74014853d7d4ceb84de55452c5ad1e75e81361 100644 (file)
@@ -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);
index efd27342aed5c73b51a89e1f3e45eb64e39252d7..8fbbe83373eaa3c843fc452268ad2cd1ad9ef427 100644 (file)
@@ -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
index 9036156d6b6d4425cbc98d38bcfcc95739865044..01effda2e30beed7f5c14962d0d734e7f6d854ed 100644 (file)
@@ -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;
index 5cc087e857e8db98e4f04b77a81615bb61578efe..9fd924f7e7af02b48f20901f623a036fa8f3fbc8 100644 (file)
 
 #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;
 
index 70ced6e59d63663a921ab7b6c3eec7db88c19bf8..495d50725d0cad4cc83252fff498e1f1b56c99e6 100644 (file)
@@ -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;
 }
 
index bef372e39f19c21f7215576dd01dddbad4a20632..bd747bc1b61de210037bf3c9fbe9b30c1f8314ff 100644 (file)
@@ -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;
 }
index 8e5b7ff06ed1697ecc750b734aa7199788165906..5fb5ada09c0081a37db45e50f320a595a5403db1 100644 (file)
@@ -8452,10 +8452,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                IpoCurve *icu;
                
                /* fix IPO-curves to work with new interpolation options */
-               for (ipo=main->ipo.first; ipo; ipo= ipo->id.next) {
-                       for (icu= ipo->curve.first; icu; icu= icu->next) 
-                               set_interpolation_ipocurve(icu, icu->ipo);
-               }
+               //for (ipo=main->ipo.first; ipo; ipo= ipo->id.next) {
+               //      for (icu= ipo->curve.first; icu; icu= icu->next) 
+               //              set_interpolation_ipocurve(icu, icu->ipo); // function removed (XXX add it here)
+               //}
                
                /* adjust default settings for Animation Editors */
                for (sc= main->screen.first; sc; sc= sc->id.next) {
index e6b8293071f03df5dd70ac1005db4e4025f010bf..2bf433dab463be98f601ff4e8c392e5b3017c2be 100644 (file)
@@ -524,7 +524,7 @@ static int animdata_filter_ipocurves (ListBase *anim_data, Ipo *ipo, int filter_
                /* only work with this channel and its subchannels if it is editable */
                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_ICU(icu)) {
                        /* only include this curve if selected or we are including all IPO-curves */
-                       if (!(filter_mode & ANIMFILTER_SEL) || (filter_mode & ANIMFILTER_ONLYICU) || (SEL_ICU(icu))) {
+                       if (!(filter_mode & ANIMFILTER_SEL) || (filter_mode & ANIMFILTER_ONLYFCU) || (SEL_ICU(icu))) {
                                /* owner/ownertype will be either object or action-channel, depending if it was dopesheet or part of an action */
                                ale= make_new_animlistelem(icu, ANIMTYPE_ICU, owner, ownertype);
                                
@@ -556,7 +556,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a
                        /* check if this achan should only be included if it is selected */
                        if (!(filter_mode & ANIMFILTER_SEL) || SEL_ACHAN(achan)) {
                                /* are we only interested in the ipo-curves? */
-                               if ((filter_mode & ANIMFILTER_ONLYICU)==0) {
+                               if ((filter_mode & ANIMFILTER_ONLYFCU)==0) {
                                        ale= make_new_animlistelem(achan, ANIMTYPE_ACHAN, achan, ANIMTYPE_ACHAN);
                                        
                                        if (ale) {
@@ -572,7 +572,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a
                        }
                        
                        /* check if expanded - if not, continue on to next animion channel */
-                       if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ANIMFILTER_ONLYICU)==0) {
+                       if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ANIMFILTER_ONLYFCU)==0) {
                                /* only exit if we don't need to include constraint channels for group-channel keyframes */
                                if ( !(filter_mode & ANIMFILTER_IPOKEYS) || (achan->grp == NULL) || (EXPANDED_AGRP(achan->grp)==0) )
                                        return items;
@@ -581,7 +581,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a
                        /* ipo channels */
                        if ((achan->ipo) && (filter_mode & ANIMFILTER_IPOKEYS)==0) {
                                /* include ipo-expand widget? */
-                               if ((filter_mode & ANIMFILTER_CHANNELS) && (filter_mode & ANIMFILTER_ONLYICU)==0) {
+                               if ((filter_mode & ANIMFILTER_CHANNELS) && (filter_mode & ANIMFILTER_ONLYFCU)==0) {
                                        ale= make_new_animlistelem(achan, ANIMTYPE_FILLIPO, achan, ANIMTYPE_ACHAN);
                                        
                                        if (ale) {
@@ -592,7 +592,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a
                                }
                                
                                /* add ipo-curve channels? */
-                               if (FILTER_IPO_ACHAN(achan) || (filter_mode & ANIMFILTER_ONLYICU)) {
+                               if (FILTER_IPO_ACHAN(achan) || (filter_mode & ANIMFILTER_ONLYFCU)) {
                                        /* loop through ipo-curve channels, adding them */
                                        items += animdata_filter_ipocurves(anim_data, achan->ipo, filter_mode, achan, ANIMTYPE_ACHAN, (owned)?(owner):(NULL));
                                }
@@ -601,7 +601,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a
                        /* constraint channels */
                        if (achan->constraintChannels.first) {
                                /* include constraint-expand widget? */
-                               if ( (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_ONLYICU)
+                               if ( (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_ONLYFCU)
                                         && !(filter_mode & ANIMFILTER_IPOKEYS) ) 
                                {
                                        ale= make_new_animlistelem(achan, ANIMTYPE_FILLCON, achan, ANIMTYPE_ACHAN);
@@ -614,7 +614,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a
                                }
                                
                                /* add constraint channels? */
-                               if (FILTER_CON_ACHAN(achan) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+                               if (FILTER_CON_ACHAN(achan) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYFCU)) {
                                        /* loop through constraint channels, checking and adding them */
                                        for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                                /* only work with this channel and its subchannels if it is editable */
@@ -662,7 +662,7 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
        /* loop over groups */
        for (agrp= act->groups.first; agrp; agrp= agrp->next) {
                /* add this group as a channel first */
-               if (!(filter_mode & ANIMFILTER_ONLYICU) && !(filter_mode & ANIMFILTER_IPOKEYS)) {
+               if (!(filter_mode & ANIMFILTER_ONLYFCU) && !(filter_mode & ANIMFILTER_IPOKEYS)) {
                        /* check if filtering by selection */
                        if ( !(filter_mode & ANIMFILTER_SEL) || SEL_AGRP(agrp) ) {
                                ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE);
@@ -691,7 +691,7 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
                         *      - we're interested in keyframes, but not if they appear in selected channels
                         */
                        if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) || 
-                                ( ((filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) && 
+                                ( ((filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYFCU)) && 
                                   (!(filter_mode & ANIMFILTER_SEL) || (SEL_AGRP(agrp))) ) ) 
                        {
                                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {                                       
@@ -798,7 +798,7 @@ static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter
        int items = 0;
        
        /* check if filtering types are appropriate */
-       if ( !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU|ANIMFILTER_ACTGROUPED)) ) 
+       if ( !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYFCU|ANIMFILTER_ACTGROUPED)) ) 
        {
                /* special hack for fullscreen area (which must be this one then):
                 *      - we use the curarea->full as screen to get spaces from, since the
@@ -859,7 +859,7 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
        int items = 0;
        
        /* include materials-expand widget? */
-       if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU))) {
+       if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYFCU))) {
                ale= make_new_animlistelem(ob, ANIMTYPE_FILLMATD, base, ANIMTYPE_OBJECT);
                if (ale) {
                        BLI_addtail(anim_data, ale);
@@ -868,7 +868,7 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
        }
        
        /* add materials? */
-       if (FILTER_MAT_OBJC(ob) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+       if (FILTER_MAT_OBJC(ob) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYFCU)) {
                short a;
                
                /* for each material, either add channels separately, or as ipo-block */
@@ -889,7 +889,7 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
                        }
                        
                        /* add material's ipo-curve channels? */
-                       if ( (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_ONLYICU)) && 
+                       if ( (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_ONLYFCU)) && 
                                  !(filter_mode & ANIMFILTER_IPOKEYS) ) 
                        {
                                items += animdata_filter_ipocurves(anim_data, ma->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)ma);
@@ -919,7 +919,7 @@ static int animdata_filter_dopesheet_cam (ListBase *anim_data, bDopeSheet *ads,
        }
        
        /* add camera ipo-curve channels? */
-       if ( (FILTER_CAM_OBJD(ca) || (filter_mode & ANIMFILTER_ONLYICU)) && 
+       if ( (FILTER_CAM_OBJD(ca) || (filter_mode & ANIMFILTER_ONLYFCU)) && 
                  !(filter_mode & ANIMFILTER_IPOKEYS) ) 
        {
                items += animdata_filter_ipocurves(anim_data, ca->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)ca);
@@ -946,7 +946,7 @@ static int animdata_filter_dopesheet_lamp (ListBase *anim_data, bDopeSheet *ads,
        }
        
        /* add lamp ipo-curve channels? */
-       if ( (FILTER_LAM_OBJD(la) || (filter_mode & ANIMFILTER_ONLYICU)) && 
+       if ( (FILTER_LAM_OBJD(la) || (filter_mode & ANIMFILTER_ONLYFCU)) && 
                  !(filter_mode & ANIMFILTER_IPOKEYS) ) 
        {
                items += animdata_filter_ipocurves(anim_data, la->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)la);
@@ -973,7 +973,7 @@ static int animdata_filter_dopesheet_curve (ListBase *anim_data, bDopeSheet *ads
        }
        
        /* add curve ipo-curve channels? */
-       if ( (FILTER_CUR_OBJD(cu) || (filter_mode & ANIMFILTER_ONLYICU)) && 
+       if ( (FILTER_CUR_OBJD(cu) || (filter_mode & ANIMFILTER_ONLYFCU)) && 
                  !(filter_mode & ANIMFILTER_IPOKEYS) ) 
        {
                items += animdata_filter_ipocurves(anim_data, cu->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)cu);
@@ -992,7 +992,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
        int items = 0;
        
        /* add this object as a channel first */
-       if (!(filter_mode & ANIMFILTER_ONLYICU) && !(filter_mode & ANIMFILTER_IPOKEYS)) {
+       if (!(filter_mode & ANIMFILTER_ONLYFCU) && !(filter_mode & ANIMFILTER_IPOKEYS)) {
                /* check if filtering by selection */
                if ( !(filter_mode & ANIMFILTER_SEL) || ((base->flag & SELECT) || (base == sce->basact)) ) {
                        ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE);
@@ -1004,7 +1004,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
        }
        
        /* if collapsed, don't go any further (unless adding keyframes only) */
-       if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU)) )
+       if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYFCU)) )
                return items;
        
        /* IPO? */
@@ -1019,7 +1019,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
                }
                
                /* add ipo-curve channels? */
-               if ( (FILTER_IPO_OBJC(ob) || (filter_mode & ANIMFILTER_ONLYICU)) && 
+               if ( (FILTER_IPO_OBJC(ob) || (filter_mode & ANIMFILTER_ONLYFCU)) && 
                          !(filter_mode & ANIMFILTER_IPOKEYS) ) 
                {
                        items += animdata_filter_ipocurves(anim_data, ob->ipo, filter_mode, base, ANIMTYPE_OBJECT, NULL); // err... why not set ob?
@@ -1029,7 +1029,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
        /* Action? */
        if ((ob->action) && !(ads->filterflag & ADS_FILTER_NOACTS)) {
                /* include animion-expand widget? */
-               if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU))) {
+               if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYFCU))) {
                        ale= make_new_animlistelem(ob->action, ANIMTYPE_FILLACTD, base, ANIMTYPE_OBJECT);
                        if (ale) {
                                ale->id= (ID *)ob; // err.... is this a good idea?
@@ -1048,7 +1048,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
        /* ShapeKeys? */
        if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
                /* include shapekey-expand widget? */
-               if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU))) {
+               if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYFCU))) {
                        ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT);
                        if (ale) {
                                BLI_addtail(anim_data, ale);
@@ -1057,7 +1057,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
                }
                
                /* add channels */
-               if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+               if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYFCU)) {
                        items += animdata_filter_shapekey(anim_data, key, filter_mode, ob, ANIMTYPE_OBJECT);
                }
        }
@@ -1096,7 +1096,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
                bConstraintChannel *conchan;
                
                /* include constraint-expand widget? */
-               if ( (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_ONLYICU)
+               if ( (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_ONLYFCU)
                         && !(filter_mode & ANIMFILTER_IPOKEYS) ) 
                {
                        ale= make_new_animlistelem(ob, ANIMTYPE_FILLCOND, base, ANIMTYPE_OBJECT);
@@ -1107,7 +1107,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
                }
                
                /* add constraint channels? */
-               if (FILTER_CON_OBJC(ob) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+               if (FILTER_CON_OBJC(ob) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYFCU)) {
                        /* loop through constraint channels, checking and adding them */
                        for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) {
                                /* only work with this channel and its subchannels if it is editable */
index 503e083d0615483997858abbf5c8376e7df2e96b..8ef7eedb4c099a0036a75094c31a63acb865b8a6 100644 (file)
@@ -52,6 +52,7 @@
 #include "WM_types.h"
 
 #include "ED_anim_api.h"
+#include "ED_keyframing.h" // XXX remove?
 #include "ED_markers.h"
 #include "ED_screen.h"
 
@@ -359,6 +360,10 @@ void ED_operatortypes_anim(void)
        
        WM_operatortype_append(ANIM_OT_previewrange_define);
        WM_operatortype_append(ANIM_OT_previewrange_clear);
+       
+               // XXX this is used all over... maybe for screen instead?
+       WM_operatortype_append(ANIM_OT_insert_keyframe);
+       WM_operatortype_append(ANIM_OT_delete_keyframe);
 }
 
 void ED_keymap_anim(wmWindowManager *wm)
index 6f1f454b90729f7aca54390cfa6af6e7e4b81ded..b38cbde741027d5e9d03f81594476e777501bb6f 100644 (file)
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
+#include "DNA_ipo_types.h" // XXX to be phased out
 #include "DNA_key_types.h"
 #include "DNA_object_types.h"
 #include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 
 #include "BKE_action.h"
-#include "BKE_ipo.h"
+#include "BKE_fcurve.h"
 #include "BKE_key.h"
 #include "BKE_utildefines.h"
 
@@ -218,16 +219,16 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
        int filter;
        
        /* filter animation data */
-       filter= ANIMFILTER_ONLYICU;
+       filter= ANIMFILTER_ONLYFCU; 
        ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
        
        /* loop over ipo-curves that are likely to have been edited, and check them */
        for (ale= anim_data.first; ale; ale= ale->next) {
-               IpoCurve *icu= ale->key_data;
+               FCurve *fcu= ale->key_data;
                
                /* make sure keyframes in IPO-curve are all in order, and handles are in valid positions */
-               sort_time_ipocurve(icu);
-               testhandles_ipocurve(icu);
+               sort_time_fcurve(fcu);
+               testhandles_fcurve(fcu);
        }
        
        /* free temp data */
@@ -404,56 +405,6 @@ BeztEditFunc ANIM_editkeyframes_mirror(short type)
        }
 }
 
-/* --------- */
-
-/* This function is called to calculate the average location of the
- * selected keyframes, and place the current frame at that location.
- *
- * It must be called like so:
- *     snap_cfra_ipo_keys(scene, NULL, -1); // initialise the static vars first
- *     for (ipo...) snap_cfra_ipo_keys(scene, ipo, 0); // sum up keyframe times
- *     snap_cfra_ipo_keys(scene, NULL, 1); // set current frame after taking average
- */
-// XXX this thing needs to be refactored!
-void snap_cfra_ipo_keys(BeztEditData *bed, Ipo *ipo, short mode)
-{
-       static int cfra;
-       static int tot;
-       
-       Scene *scene= bed->scene;
-       IpoCurve *icu;
-       BezTriple *bezt;
-       int a;
-       
-       
-       if (mode == -1) {
-               /* initialise a new snap-operation */
-               cfra= 0;
-               tot= 0;
-       }
-       else if (mode == 1) {
-               /* set current frame - using average frame */
-               if (tot != 0)
-                       CFRA = cfra / tot;
-       }
-       else {
-               /* loop through keys in ipo, summing the frame
-                * numbers of those that are selected 
-                */
-               if (ipo == NULL) 
-                       return;
-               
-               for (icu= ipo->curve.first; icu; icu= icu->next) {
-                       for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
-                               if (BEZSELECTED(bezt)) {
-                                       cfra += (int)floor(bezt->vec[1][0] + 0.5f);
-                                       tot++;
-                               }
-                       }
-               }
-       }       
-}
-
 /* ******************************************* */
 /* Settings */
 
@@ -548,7 +499,7 @@ void ANIM_editkeyframes_ipocurve_ipotype(IpoCurve *icu)
        icu->ipo= IPO_MIXED;
        
        /* recalculate handles, as some changes may have occurred */
-       calchandles_ipocurve(icu);
+       //calchandles_ipocurve(icu);    // XXX
 }
 
 static short set_bezt_constant(BeztEditData *bed, BezTriple *bezt) 
index 57a4d6952c77b036e26a56c8d8d16b0a40b3def5..8ff65a2a00895f16efaeee047945a18aedf98707 100644 (file)
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
+#include "DNA_ipo_types.h" // XXX to be removed
 #include "DNA_key_types.h"
 #include "DNA_object_types.h"
 #include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 
 #include "BKE_action.h"
-#include "BKE_ipo.h"
+#include "BKE_fcurve.h"
 #include "BKE_key.h"
 #include "BKE_utildefines.h"
 
  * Not recommended to be used many times successively. For that
  * there is delete_ipo_keys(). 
  */
-void delete_icu_key(IpoCurve *icu, int index, short do_recalc)
+void delete_fcurve_key(FCurve *fcu, int index, short do_recalc)
 {
        /* firstly check that index is valid */
        if (index < 0) 
                index *= -1;
-       if (icu == NULL) 
+       if (fcu == NULL) 
                return;
-       if (index >= icu->totvert)
+       if (index >= fcu->totvert)
                return;
        
        /*      Delete this key */
-       memmove(&icu->bezt[index], &icu->bezt[index+1], sizeof(BezTriple)*(icu->totvert-index-1));
-       icu->totvert--;
+       memmove(&fcu->bezt[index], &fcu->bezt[index+1], sizeof(BezTriple)*(fcu->totvert-index-1));
+       fcu->totvert--;
        
        /* recalc handles - only if it won't cause problems */
        if (do_recalc)
-               calchandles_ipocurve(icu);
+               calchandles_fcurve(fcu);
 }
 
+#if 0 // XXX obsolete
 /* Delete selected keyframes in given IPO block */
 void delete_ipo_keys(Ipo *ipo)
 {
@@ -117,6 +119,7 @@ void delete_ipo_keys(Ipo *ipo)
                }
        }
 }
+#endif // XXX obsolete
 
 /* ---------------- */
 
@@ -160,26 +163,31 @@ void duplicate_ipo_keys(Ipo *ipo)
 /* **************************************************** */
 /* Various Tools */
 
+// XXX - stub... until keyframing code is fixed...
+static void insert_vert_fcu(FCurve *fcu, float x, float y, short flag)
+{
+}
+
 /* Basic IPO-Curve 'cleanup' function that removes 'double points' and unnecessary keyframes on linear-segments only */
-void clean_ipo_curve(IpoCurve *icu, float thresh)
+void clean_fcurve(FCurve *fcu, float thresh)
 {
        BezTriple *old_bezts, *bezt, *beztn;
        BezTriple *lastb;
        int totCount, i;
        
        /* check if any points  */
-       if ((icu == NULL) || (icu->totvert <= 1)) 
+       if ((fcu == NULL) || (fcu->totvert <= 1)) 
                return;
        
        /* make a copy of the old BezTriples, and clear IPO curve */
-       old_bezts = icu->bezt;
-       totCount = icu->totvert;        
-       icu->bezt = NULL;
-       icu->totvert = 0;
+       old_bezts = fcu->bezt;
+       totCount = fcu->totvert;        
+       fcu->bezt = NULL;
+       fcu->totvert = 0;
        
        /* now insert first keyframe, as it should be ok */
        bezt = old_bezts;
-       insert_vert_icu(icu, bezt->vec[1][0], bezt->vec[1][1], 0);
+       insert_vert_fcu(fcu, bezt->vec[1][0], bezt->vec[1][1], 0);
        
        /* Loop through BezTriples, comparing them. Skip any that do 
         * not fit the criteria for "ok" points.
@@ -196,7 +204,7 @@ void clean_ipo_curve(IpoCurve *icu, float thresh)
                        beztn = NULL;
                        next[0] = next[1] = 0.0f;
                }
-               lastb= (icu->bezt + (icu->totvert - 1));
+               lastb= (fcu->bezt + (fcu->totvert - 1));
                bezt= (old_bezts + i);
                
                /* get references for quicker access */
@@ -216,7 +224,7 @@ void clean_ipo_curve(IpoCurve *icu, float thresh)
                                if (cur[1] > next[1]) {
                                        if (IS_EQT(cur[1], prev[1], thresh) == 0) {
                                                /* add new keyframe */
-                                               insert_vert_icu(icu, cur[0], cur[1], 0);
+                                               insert_vert_fcu(fcu, cur[0], cur[1], 0);
                                        }
                                }
                        }
@@ -224,7 +232,7 @@ void clean_ipo_curve(IpoCurve *icu, float thresh)
                                /* only add if values are a considerable distance apart */
                                if (IS_EQT(cur[1], prev[1], thresh) == 0) {
                                        /* add new keyframe */
-                                       insert_vert_icu(icu, cur[0], cur[1], 0);
+                                       insert_vert_fcu(fcu, cur[0], cur[1], 0);
                                }
                        }
                }
@@ -234,18 +242,18 @@ void clean_ipo_curve(IpoCurve *icu, float thresh)
                                /* does current have same value as previous and next? */
                                if (IS_EQT(cur[1], prev[1], thresh) == 0) {
                                        /* add new keyframe*/
-                                       insert_vert_icu(icu, cur[0], cur[1], 0);
+                                       insert_vert_fcu(fcu, cur[0], cur[1], 0);
                                }
                                else if (IS_EQT(cur[1], next[1], thresh) == 0) {
                                        /* add new keyframe */
-                                       insert_vert_icu(icu, cur[0], cur[1], 0);
+                                       insert_vert_fcu(fcu, cur[0], cur[1], 0);
                                }
                        }
                        else {  
                                /* add if value doesn't equal that of previous */
                                if (IS_EQT(cur[1], prev[1], thresh) == 0) {
                                        /* add new keyframe */
-                                       insert_vert_icu(icu, cur[0], cur[1], 0);
+                                       insert_vert_fcu(fcu, cur[0], cur[1], 0);
                                }
                        }
                }
@@ -264,8 +272,8 @@ typedef struct tSmooth_Bezt {
 } tSmooth_Bezt;
 
 /* Use a weighted moving-means method to reduce intensity of fluctuations */
-//mode= pupmenu("Smooth IPO%t|Tweak Points%x1|Flatten Handles%x2");
-void smooth_ipo_curve(IpoCurve *icu, short mode)
+//mode= pupmenu("Smooth F-Curve%t|Tweak Points%x1|Flatten Handles%x2");
+void smooth_fcurve(FCurve *fcu, short mode)
 {
        BezTriple *bezt;
        int i, x, totSel = 0;
@@ -273,8 +281,8 @@ void smooth_ipo_curve(IpoCurve *icu, short mode)
        /* first loop through - count how many verts are selected, and fix up handles 
         *      this is done for both modes
         */
-       bezt= icu->bezt;
-       for (i=0; i < icu->totvert; i++, bezt++) {                                              
+       bezt= fcu->bezt;
+       for (i=0; i < fcu->totvert; i++, bezt++) {                                              
                if (BEZSELECTED(bezt)) {                                                        
                        /* line point's handles up with point's vertical position */
                        bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
@@ -296,8 +304,8 @@ void smooth_ipo_curve(IpoCurve *icu, short mode)
                        tsb= tarray= MEM_callocN(totSel*sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
                        
                        /* populate tarray with data of selected points */
-                       bezt= icu->bezt;
-                       for (i=0, x=0; (i < icu->totvert) && (x < totSel); i++, bezt++) {
+                       bezt= fcu->bezt;
+                       for (i=0, x=0; (i < fcu->totvert) && (x < totSel); i++, bezt++) {
                                if (BEZSELECTED(bezt)) {
                                        /* tsb simply needs pointer to vec, and index */
                                        tsb->h1 = &bezt->vec[0][1];
@@ -358,7 +366,7 @@ void smooth_ipo_curve(IpoCurve *icu, short mode)
        }
        
        /* recalculate handles */
-       calchandles_ipocurve(icu);
+       calchandles_fcurve(fcu);
 }
 
 /* **************************************************** */
index 5121932d0ccaa9d533bfd0f7c2b8d73b3032f9f9..4f62368c2b2717fba8e4c3b333089cc6690187e3 100644 (file)
-/**
- * $Id: keyframing.c 17745 2008-12-08 09:16:09Z aligorith $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2008, Blender Foundation
- * This is a new part of Blender (with some old code)
- *
- * Contributor(s): Joshua Leung
- *
- * ***** END GPL LICENSE BLOCK *****
+/* Testing code for 2.5 animation system 
+ * Copyright 2009, Joshua Leung
  */
-
-
-
 #include <stdio.h>
 #include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
 #include <math.h>
 #include <float.h>
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include "MEM_guardedalloc.h"
 
-#include "BLI_arithb.h"
 #include "BLI_blenlib.h"
+#include "BLI_arithb.h"
 #include "BLI_dynstr.h"
 
-#include "DNA_listBase.h"
-#include "DNA_ID.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_ipo_types.h"
 #include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
 #include "DNA_object_types.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_particle_types.h"
 #include "DNA_material_types.h"
-#include "DNA_screen_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_space_types.h"
-#include "DNA_texture_types.h"
 #include "DNA_userdef_types.h"
-#include "DNA_vec_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_world_types.h"
 #include "DNA_windowmanager_types.h"
 
-#include "BKE_context.h"
-#include "BKE_utildefines.h"
-#include "BKE_blender.h"
+#include "BKE_animsys.h"
 #include "BKE_action.h"
-#include "BKE_armature.h"
-#include "BKE_constraint.h"
-#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
-#include "BKE_ipo.h"
+#include "BKE_fcurve.h"
+#include "BKE_utildefines.h"
+#include "BKE_context.h"
 #include "BKE_key.h"
-#include "BKE_object.h"
-#include "BKE_particle.h"
 #include "BKE_material.h"
-#include "BKE_modifier.h"
 
 #include "ED_anim_api.h"
 #include "ED_keyframing.h"
 #include "ED_keyframes_edit.h"
+#include "ED_screen.h"
+#include "ED_util.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
 
-#if 0 // XXX resolve these old dependencies!
-       #include "BIF_butspace.h"
-       #include "BIF_editaction.h"
-       #include "BIF_editkey.h"
-       #include "BIF_interface.h"
-       #include "BIF_mywindow.h"
-       #include "BIF_poseobject.h"
-       #include "BIF_screen.h"
-       #include "BIF_space.h"
-       #include "BIF_toolbox.h"
-       #include "BIF_toets.h"
-
-       #include "BSE_editipo.h"
-       #include "BSE_node.h"
-       #include "BSE_time.h"
-       #include "BSE_view.h"
-
-       #include "blendef.h"
-
-       #include "PIL_time.h"                   /* sleep                                */
-       #include "mydevice.h"
-#endif // XXX resolve these old dependencies!
-
-/* ****************************************** */
-
-/* note for Joshua: add_ipo() wants scene pointer to init the view2d 'cur' for
-   the ipo data, which restores views. Needs to be resolved nicer? */
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
 
 /* ************************************************** */
 /* LOCAL TYPES AND DEFINES */
@@ -130,34 +55,15 @@ typedef struct bCommonKeySrc {
                
                /* general data/destination-source settings */
        ID *id;                                 /* id-block this comes from */
-       char *actname;                  /* name of action channel */
-       char *constname;                /* name of constraint channel */
+       char *rna_path;                 /* base path to use */  // xxx.... maybe we don't need this?
        
-               /* general destination source settings */
-       Ipo *ipo;                               /* ipo-block that id-block has (optional) */
-       bAction *act;                   /* action-block that id-block has (optional) */
-       
-               /* pose-level settings */
-       bPoseChannel *pchan;    /* pose channel */
-               
-               /* buttons-window settings */
-       int map;                                /* offset to apply to certain adrcodes */
+               /* specific cases */
+       bPoseChannel *pchan;    /* only needed when doing recalcs... */
 } bCommonKeySrc;
 
 /* -------------- Keying Sets ------------------- */
 
-/* storage for iterator for looping over keyingset channels */
-typedef struct bKS_AdrcodeGetter {
-       struct bKeyingSet *ks;          /* keyingset this applies to */
-       struct bCommonKeySrc *cks;      /* data to insert/delete keyframes... */
-       
-       short index;                            /* index of current channel to resume from */
-       short tot;                                      /* index after which we start returning from some special collection */
-} bKS_AdrcodeGetter;
-
-/* flags to look out for in keyingset channels... */
-#define KAG_CHAN_EXTEND                (-1)
-
+#if 0 // XXX I'm not sure how these will work for now...
 
 /* keying set - a set of channels that will be keyframed together  */
 // TODO: move this to a header to allow custom sets someday?
@@ -168,11 +74,11 @@ typedef struct bKeyingSet {
        short (*include_cb)(struct bKeyingSet *, const char *);
        
        char name[48];                          /* name of keyingset */
-       int blocktype;                          /* blocktype that all channels belong to */  // in future, this may be eliminated
+       int blocktype;                          /* nearest ID-blocktype to where data can be found */
        short flag;                                     /* flags to use when setting keyframes */
        
        short chan_num;                         /* number of channels to insert keyframe in */
-       short adrcodes[32];                     /* adrcodes for channels to insert keys for (ideally would be variable-len, but limit of 32 will suffice) */
+       char (*paths)[256];                     /* adrcodes for channels to insert keys for (ideally would be variable-len, but limit of 32 will suffice) */
 } bKeyingSet;
 
 /* keying set context - an array of keying sets and the number of them */
@@ -182,282 +88,57 @@ typedef struct bKeyingContext {
        int tot;                                        /* number of keyingsets in */
 } bKeyingContext;
 
+#endif
 
-/* ************************************************** */
-/* IPO DATA VERIFICATION */
-// XXX these will need to be modified for use with RNA-IPO...
-
-/* depending type, it returns ipo, if needed it creates one */
-/* returns either action ipo or "real" ipo */
-/* arguments define full context;
-   - *from has to be set always, to Object in case of Actions
-   - blocktype defines available channels of Ipo struct (blocktype ID_OB can be in action too)
-   - if actname, use this to locate actionchannel, and optional constname 
-   - if bonename, the constname is the ipo to the constraint
-*/
-
-/* note: check header_ipo.c, spaceipo_assign_ipo() too */
-Ipo *verify_ipo(ID *from, short blocktype, char actname[], char constname[], char bonename[], short add)
-{
-       /* lib-linked data is not appropriate here */
-       if ((from==NULL) || (from->lib))
-               return NULL;
-       
-       /* first check action ipos */
-       if (actname && actname[0]) {
-               Object *ob= (Object *)from;
-               bActionChannel *achan;
-               
-               if (GS(from->name)!=ID_OB) {
-                       printf("called ipo system for action with wrong base pointer\n");
-                       return NULL;
-               }
-               
-               if ((ob->action==NULL) && (add))
-                       ob->action= add_empty_action("Action");
-               
-               if (add)
-                       achan= verify_action_channel(ob->action, actname);
-               else    
-                       achan= get_action_channel(ob->action, actname);
-               
-               if (achan) {
-                       /* automatically assign achan to act-group based on pchan's grouping */
-                       //if ((blocktype == ID_PO) && (add))
-                       //      verify_pchan2achan_grouping(ob->action, ob->pose, actname);
-                       
-                       /* constraint exception */
-                       if (blocktype==ID_CO) {
-                               bConstraintChannel *conchan;
-                               
-                               if (add)
-                                       conchan= verify_constraint_channel(&achan->constraintChannels, constname);
-                               else
-                                       conchan= get_constraint_channel(&achan->constraintChannels, constname);
-                                       
-                               if (conchan) {
-                                       if ((conchan->ipo==NULL) && (add))
-                                               conchan->ipo= add_ipo(NULL, "CoIpo", ID_CO);    
-                                       return conchan->ipo;
-                               }
-                       }
-                       else {
-                               if ((achan->ipo==NULL) && (add))
-                                       achan->ipo= add_ipo(NULL, "ActIpo", blocktype);
-                               return achan->ipo;
-                       }
-               }
-       }
-       else {
-               switch (GS(from->name)) {
-               case ID_OB:
-                       {
-                               Object *ob= (Object *)from;
-                               
-                               /* constraint exception */
-                               if (blocktype==ID_CO) {
-                                       /* check the local constraint ipo */
-                                       if (bonename && bonename[0] && ob->pose) {
-                                               bPoseChannel *pchan= get_pose_channel(ob->pose, bonename);
-                                               bConstraint *con;
-                                               
-                                               for (con= pchan->constraints.first; con; con= con->next) {
-                                                       if (strcmp(con->name, constname)==0)
-                                                               break;
-                                               }
-                                               
-                                               if (con) {
-                                                       if ((con->ipo==NULL) && (add))
-                                                               con->ipo= add_ipo(NULL, "CoIpo", ID_CO);
-                                                       return con->ipo;
-                                               }
-                                       }
-                                       else { /* the actionchannel */
-                                               bConstraintChannel *conchan;
-                                               
-                                               if (add)
-                                                       conchan= verify_constraint_channel(&ob->constraintChannels, constname);
-                                               else
-                                                       conchan= get_constraint_channel(&ob->constraintChannels, constname);
-                                                       
-                                               if (conchan) {
-                                                       if ((conchan->ipo==NULL) && (add))
-                                                               conchan->ipo= add_ipo(NULL, "CoIpo", ID_CO);    
-                                                       return conchan->ipo;
-                                               }
-                                       }
-                               }
-                               else if (blocktype==ID_OB) {
-                                       if ((ob->ipo==NULL) && (add))
-                                               ob->ipo= add_ipo(NULL, "ObIpo", ID_OB);
-                                       return ob->ipo;
-                               }
-                               else if (blocktype==ID_KE) {
-                                       Key *key= ob_get_key((Object *)from);
-                                       
-                                       if (key) {
-                                               if ((key->ipo==NULL) && (add))
-                                                       key->ipo= add_ipo(NULL, "KeyIpo", ID_KE);
-                                               return key->ipo;
-                                       }
-                                       return NULL;
-                               }
-                               else if (blocktype== ID_FLUIDSIM) {
-                                       Object *ob= (Object *)from;
-
-                                       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
-                                       if(fluidmd) {
-                                               FluidsimSettings *fss= fluidmd->fss;
-                                               
-                                               if ((fss->ipo==NULL) && (add))
-                                                       fss->ipo= add_ipo(NULL, "FluidsimIpo", ID_FLUIDSIM);
-                                               return fss->ipo;
-                                       }
-                               }
-                               else if(blocktype== ID_PA) {
-                                       Object *ob= (Object *)from;
-                                       ParticleSystem *psys= psys_get_current(ob);
-                                       
-                                       if (psys) {
-                                               if ((psys->part->ipo==NULL) && (add))
-                                                       psys->part->ipo= add_ipo(NULL, "ParticleIpo", ID_PA);
-                                               return psys->part->ipo;
-                                       }
-                                       return NULL;
-                               }
-                       }
-                       break;
-               case ID_MA:
-                       {
-                               Material *ma= (Material *)from;
-                               
-                               if ((ma->ipo==NULL) && (add))
-                                       ma->ipo= add_ipo(NULL, "MatIpo", ID_MA);
-                               return ma->ipo;
-                       }
-                       break;
-               case ID_TE:
-                       {
-                               Tex *tex= (Tex *)from;
-                               
-                               if ((tex->ipo==NULL) && (add))
-                                       tex->ipo= add_ipo(NULL, "TexIpo", ID_TE);
-                               return tex->ipo;
-                       }
-                       break;
-               case ID_SEQ:
-                       {
-                               Sequence *seq= (Sequence *)from;        /* note, sequence is mimicing Id */
-                               
-                               if ((seq->ipo==NULL) && (add))
-                                       seq->ipo= add_ipo(NULL, "SeqIpo", ID_SEQ);
-                               //update_seq_ipo_rect(seq); // XXX
-                               return seq->ipo;
-                       }
-                       break;
-               case ID_CU:
-                       {
-                               Curve *cu= (Curve *)from;
-                               
-                               if ((cu->ipo==NULL) && (add))
-                                       cu->ipo= add_ipo(NULL, "CuIpo", ID_CU);
-                               return cu->ipo;
-                       }
-                       break;
-               case ID_WO:
-                       {
-                               World *wo= (World *)from;
-                               
-                               if ((wo->ipo==NULL) && (add))
-                                       wo->ipo= add_ipo(NULL, "WoIpo", ID_WO);
-                               return wo->ipo;
-                       }
-                       break;
-               case ID_LA:
-                       {
-                               Lamp *la= (Lamp *)from;
-                               
-                               if ((la->ipo==NULL) && (add))
-                                       la->ipo= add_ipo(NULL, "LaIpo", ID_LA);
-                               return la->ipo;
-                       }
-                       break;
-               case ID_CA:
-                       {
-                               Camera *ca= (Camera *)from;
-                               
-                               if ((ca->ipo==NULL) && (add))
-                                       ca->ipo= add_ipo(NULL, "CaIpo", ID_CA);
-                               return ca->ipo;
-                       }
-                       break;
-               case ID_SO:
-                       {
-#if 0 // depreceated
-                               bSound *snd= (bSound *)from;
-                               
-                               if ((snd->ipo==NULL) && (add))
-                                       snd->ipo= add_ipo(NULL, "SndIpo", ID_SO);
-                               return snd->ipo;
-#endif // depreceated
-                       }       
-                       break;
-               }
-       }
-       
-       return NULL;    
-}
+/* ******************************************* */
+/* Animation Data Validation */
 
-/* Returns and creates
- * Make sure functions check for NULL or they will crash!
+/* Get (or add relevant data to be able to do so) F-Curve from the Active Action, 
+ * for the given Animation Data block 
  */
-IpoCurve *verify_ipocurve(ID *from, short blocktype, char actname[], char constname[], char bonename[], int adrcode, short add)
+// TODO: should we check if path is valid? For now, assume that it's already set OK by caller...
+FCurve *verify_fcurve (AnimData *adt, const char rna_path[], const int array_index, short add)
 {
-       Ipo *ipo;
-       IpoCurve *icu= NULL;
+       nAction *act;
+       FCurve *fcu;
        
-       /* return 0 if lib */
-       /* creates ipo too (if add) */
-       ipo= verify_ipo(from, blocktype, actname, constname, bonename, add);
+       /* sanity checks */
+       if ELEM(NULL, adt, rna_path)
+               return NULL;
+               
+       /* init action if none available yet */
+       // TODO: need some wizardry to handle NLA stuff correct
+       if ((adt->action == NULL) && (add))
+               adt->action= add_empty_action("Action");
+       act= adt->action;
+               
+       /* try to find f-curve matching for this setting 
+        *      - add if not found and allowed to add one
+        *              TODO: add auto-grouping support? how this works will need to be resolved
+        */
+       if (act)
+               fcu= list_find_fcurve(&act->curves, rna_path, array_index);
+       else
+               fcu= NULL;
        
-       if ((ipo) && (ipo->id.lib==NULL) && (from->lib==NULL)) {
-               /* try to find matching curve */
-               icu= find_ipocurve(ipo, adrcode);
+       if ((fcu == NULL) && (add)) {
+               /* use default settings */
+               fcu= MEM_callocN(sizeof(FCurve), "FCurve");
                
-               /* make a new one if none found (and can add) */
-               if ((icu==NULL) && (add)) {
-                       icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
-                       
-                       /* set default settings */
-                       icu->flag |= (IPO_VISIBLE|IPO_AUTO_HORIZ);
-                       if (ipo->curve.first==NULL) 
-                               icu->flag |= IPO_ACTIVE;        /* first one added active */
-                       
-                       icu->blocktype= blocktype;
-                       icu->adrcode= adrcode;
+               fcu->flag |= (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES);
+               if (act->curves.first==NULL) 
+                       fcu->flag |= FCURVE_ACTIVE;     /* first one added active */
                        
-                       set_icu_vars(icu);
-                       
-                       /* default curve interpolation - from userpref */
-                       icu->ipo= U.ipo_new;
-                       
-                       /* add curve to IPO-block */
-                       BLI_addtail(&ipo->curve, icu);
-                       
-                       /* special type-dependent stuff */
-                       switch (GS(from->name)) {
-                               case ID_SEQ: {
-                                       //Sequence *seq= (Sequence *)from;
-                                       
-                                       //update_seq_icu_rects(seq); // XXX
-                                       break;
-                               }
-                       }
-               }
+               /* store path - make copy, and store that */
+               fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path));
+               fcu->array_index= array_index;
+               
+               /* add curve */
+               BLI_addtail(&act->curves, fcu); // XXX it might be better to add this in order, for easier UI coding...
        }
        
-       /* return ipo-curve */
-       return icu;
+       /* return the F-Curve */
+       return fcu;
 }
 
 /* ************************************************** */
@@ -544,54 +225,55 @@ static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen
        return start;
 }
 
-/* This function adds a given BezTriple to an IPO-Curve. It will allocate 
+/* This function adds a given BezTriple to an F-Curve. It will allocate 
  * memory for the array if needed, and will insert the BezTriple into a
  * suitable place in chronological order.
  * 
- * NOTE: any recalculate of the IPO-Curve that needs to be done will need to 
+ * NOTE: any recalculate of the F-Curve that needs to be done will need to 
  *             be done by the caller.
  */
-int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
+int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
 {
        BezTriple *newb;
        int i= 0;
        
-       if (icu->bezt) {
+       if (fcu->bezt) {
                short replace = -1;
-               i = binarysearch_bezt_index(icu->bezt, bezt->vec[1][0], icu->totvert, &replace);
+               i = binarysearch_bezt_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace);
                
                if (replace) {                  
                        /* sanity check: 'i' may in rare cases exceed arraylen */
                        // FIXME: do not overwrite handletype if just replacing...?
-                       if ((i >= 0) && (i < icu->totvert))
-                               *(icu->bezt + i) = *bezt;
+                       if ((i >= 0) && (i < fcu->totvert))
+                               *(fcu->bezt + i) = *bezt;
                }
                else {
                        /* add new */
-                       newb= MEM_callocN((icu->totvert+1)*sizeof(BezTriple), "beztriple");
+                       newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
                        
                        /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
                        if (i > 0)
-                               memcpy(newb, icu->bezt, i*sizeof(BezTriple));
+                               memcpy(newb, fcu->bezt, i*sizeof(BezTriple));
                        
                        /* add beztriple to paste at index i */
                        *(newb + i)= *bezt;
                        
                        /* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
-                       if (i < icu->totvert) 
-                               memcpy(newb+i+1, icu->bezt+i, (icu->totvert-i)*sizeof(BezTriple));
+                       if (i < fcu->totvert) 
+                               memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple));
                        
                        /* replace (+ free) old with new */
-                       MEM_freeN(icu->bezt);
-                       icu->bezt= newb;
+                       MEM_freeN(fcu->bezt);
+                       fcu->bezt= newb;
                        
-                       icu->totvert++;
+                       fcu->totvert++;
                }
        }
        else {
-               icu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
-               *(icu->bezt)= *bezt;
-               icu->totvert= 1;
+               // TODO: need to check for old sample-data now...
+               fcu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
+               *(fcu->bezt)= *bezt;
+               fcu->totvert= 1;
        }
        
        
@@ -607,10 +289,10 @@ int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
  * 
  * 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
  */
-void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
+void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
 {
        BezTriple beztr;
-       int a, h1, h2;
+       int a;
        
        /* set all three points, for nicer start position */
        memset(&beztr, 0, sizeof(BezTriple));
@@ -620,12 +302,12 @@ void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
        beztr.vec[1][1]= y;
        beztr.vec[2][0]= x;
        beztr.vec[2][1]= y;
-       beztr.hide= IPO_BEZ;
+       beztr.ipo= U.ipo_new; /* use default interpolation mode here... */
        beztr.f1= beztr.f2= beztr.f3= SELECT;
-       beztr.h1= beztr.h2= HD_AUTO;
+       beztr.h1= beztr.h2= HD_AUTO; // XXX what about when we replace an old one?
        
        /* add temp beztriple to keyframes */
-       a= insert_bezt_icu(icu, &beztr);
+       a= insert_bezt_fcurve(fcu, &beztr);
        
        /* what if 'a' is a negative index? 
         * for now, just exit to prevent any segfaults
@@ -636,125 +318,34 @@ void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
         *      - this is a hack to make importers faster
         *      - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
         */
-       if (!fast) calchandles_ipocurve(icu);
+       if (!fast) calchandles_fcurve(fcu);
        
        /* set handletype and interpolation */
-       if (icu->totvert > 2) {
-               BezTriple *bezt= (icu->bezt + a);
+       if (fcu->totvert > 2) {
+               BezTriple *bezt= (fcu->bezt + a);
+               short h1, h2;
                
                /* set handles (autohandles by default) */
                h1= h2= HD_AUTO;
                
                if (a > 0) h1= (bezt-1)->h2;
-               if (a < icu->totvert-1) h2= (bezt+1)->h1;
+               if (a < fcu->totvert-1) h2= (bezt+1)->h1;
                
                bezt->h1= h1;
                bezt->h2= h2;
                
-               /* set interpolation (if curve is using IPO_MIXED, then take from previous) */
-               if (icu->ipo == IPO_MIXED) {
-                       if (a > 0) bezt->ipo= (bezt-1)->ipo;
-                       else if (a < icu->totvert-1) bezt->ipo= (bezt+1)->ipo;
-               }
-               else
-                       bezt->ipo= icu->ipo;
+               /* set interpolation from previous (if available) */
+               if (a > 0) bezt->ipo= (bezt-1)->ipo;
+               else if (a < fcu->totvert-1) bezt->ipo= (bezt+1)->ipo;
                        
                /* don't recalculate handles if fast is set
                 *      - this is a hack to make importers faster
                 *      - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
                 */
-               if (!fast) calchandles_ipocurve(icu);
-       }
-       else {
-               BezTriple *bezt= (icu->bezt + a);
-               
-               /* set interpolation directly from ipo-curve */
-               bezt->ipo= icu->ipo;
-       }
-}
-
-
-/* ------------------- Get Data ------------------------ */
-
-/* Get pointer to use to get values from */
-// FIXME: this should not be possible with Data-API
-static void *get_context_ipo_poin (ID *id, int blocktype, char *actname, char *constname, IpoCurve *icu, int *vartype)
-{
-       switch (blocktype) {
-               case ID_PO:  /* posechannel */
-                       if (GS(id->name)==ID_OB) {
-                               Object *ob= (Object *)id;
-                               bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
-                               
-                               if (pchan) {
-                                       if (ELEM3(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))
-                                               *vartype= IPO_FLOAT_DEGR;
-                                       else
-                                               *vartype= IPO_FLOAT;
-                                       return get_pchan_ipo_poin(pchan, icu->adrcode);
-                               }
-                       }
-                       break;
-                       
-               case ID_CO: /* constraint */
-                       if ((GS(id->name)==ID_OB) && (constname && constname[0])) {
-                               Object *ob= (Object *)id;
-                               bConstraint *con;
-                               
-                               /* assume that we only want the influence (as only used for Constraint Channels) */
-                               if ((ob->ipoflag & OB_ACTION_OB) && !strcmp(actname, "Object")) {
-                                       for (con= ob->constraints.first; con; con= con->next) {
-                                               if (strcmp(constname, con->name)==0) {
-                                                       *vartype= IPO_FLOAT;
-                                                       return &con->enforce;
-                                               }
-                                       }
-                               }
-                               else if (ob->pose) {
-                                       bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
-                                       
-                                       if (pchan) {
-                                               for (con= pchan->constraints.first; con; con= con->next) {
-                                                       if (strcmp(constname, con->name)==0) {
-                                                               *vartype= IPO_FLOAT;
-                                                               return &con->enforce;
-                                                       }
-                                               }
-                                       }
-