Keying Sets: Wrapped KeyingSets in RNA
[blender.git] / source / blender / makesdna / DNA_anim_types.h
1 /* Testing code for new animation system in 2.5 
2  * Copyright 2009, Joshua Leung
3  */
4
5 #ifndef DNA_ANIM_TYPES_H
6 #define DNA_ANIM_TYPES_H
7
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11
12 #include "DNA_ID.h"
13 #include "DNA_listBase.h"
14 #include "DNA_action_types.h"
15 #include "DNA_curve_types.h"
16
17 /* ************************************************ */
18 /* F-Curve DataTypes */
19
20 /* Modifiers -------------------------------------- */
21
22 /* F-Curve Modifiers (fcm) 
23  *
24  * These alter the way F-Curves behave, by altering the value that is returned
25  * when evaluating the curve's data at some time (t). 
26  */
27 typedef struct FModifier {
28         struct FModifier *next, *prev;
29         
30         void *data;                     /* pointer to modifier data */
31         
32         char name[64];          /* user-defined description for the modifier */
33         short type;                     /* type of f-curve modifier */
34         short flag;                     /* settings for the modifier */
35         
36         float influence;        /* the amount that the modifier should influence the value */
37 } FModifier;
38
39 /* Types of F-Curve modifier 
40  * WARNING: order here is important!
41  */
42 enum {
43         FMODIFIER_TYPE_NULL = 0,
44         FMODIFIER_TYPE_GENERATOR,
45         FMODIFIER_TYPE_ENVELOPE,
46         FMODIFIER_TYPE_CYCLES,
47         FMODIFIER_TYPE_NOISE,           /* unimplemented - generate variations using some basic noise generator... */
48         FMODIFIER_TYPE_FILTER,          /* unimplemented - for applying: fft, high/low pass filters, etc. */
49         FMODIFIER_TYPE_PYTHON,          
50         
51         /* NOTE: all new modifiers must be added above this line */
52         FMODIFIER_NUM_TYPES
53 } eFModifier_Types;
54
55 /* F-Curve Modifier Settings */
56 enum {
57                 /* modifier is not able to be evaluated for some reason, and should be skipped (internal) */
58         FMODIFIER_FLAG_DISABLED         = (1<<0),
59                 /* modifier's data is expanded (in UI) */
60         FMODIFIER_FLAG_EXPANDED         = (1<<1),
61                 /* modifier is active one (in UI) for editing purposes */
62         FMODIFIER_FLAG_ACTIVE           = (1<<2),
63 } eFModifier_Flags; 
64
65 /* --- */
66
67 /* generator modifier data */
68 typedef struct FMod_Generator {
69                 /* generator based on PyExpression */
70         char expression[256];           /* python expression to use as generator */
71         
72                 /* simple polynomial generator (y = C[0]*(x^(n)) + C[1]*(x^(n-1)) + ... C[n])  */
73         float *poly_coefficients;       /* array of the coefficients for the polynomial (poly_order + 1 items long) */
74         unsigned int poly_order;        /* order of the polynomial (i.e. 1 for linear, 2 for quadratic) */
75         
76                 /* settings */
77         short flag;                                     /* settings */
78         short mode;                                     /* which 'generator' to use */
79 } FMod_Generator;
80
81 /* generator modes */
82 enum {
83         FCM_GENERATOR_POLYNOMIAL        = 0,
84         FCM_GENERATOR_EXPRESSION,
85 } eFMod_Generator_Modes;
86
87
88 /* envelope modifier - envelope data */
89 typedef struct FCM_EnvelopeData {
90         float min, max;                         /* min/max values for envelope at this point (absolute values)  */
91         float time;                                     /* time for that this sample-point occurs */
92         
93         short f1;                                       /* settings for 'min' control point */
94         short f2;                                       /* settings for 'max' control point */
95 } FCM_EnvelopeData;
96
97 /* envelope-like adjustment to values (for fade in/out) */
98 typedef struct FMod_Envelope {
99         FCM_EnvelopeData *data;         /* data-points defining envelope to apply (array)  */
100         int totvert;                            /* number of envelope points */
101         
102         float midval;                           /* value that envelope's influence is centered around / based on */
103         float min, max;                         /* distances from 'middle-value' for 1:1 envelope influence */
104 } FMod_Envelope;
105
106
107 /* cycling/repetition modifier data */
108 // TODO: we can only do complete cycles...
109 typedef struct FMod_Cycles {
110         short   before_mode;            /* extrapolation mode to use before first keyframe */
111         short   after_mode;                     /* extrapolation mode to use after last keyframe */
112         short   before_cycles;          /* number of 'cycles' before first keyframe to do */
113         short   after_cycles;           /* number of 'cycles' after last keyframe to do */
114 } FMod_Cycles;
115
116 /* cycling modes */
117 enum {
118         FCM_EXTRAPOLATE_NONE = 0,                       /* don't do anything */
119         FCM_EXTRAPOLATE_CYCLIC,                         /* repeat keyframe range as-is */
120         FCM_EXTRAPOLATE_CYCLIC_OFFSET,          /* repeat keyframe range, but with offset based on gradient between values */
121 } eFMod_Cycling_Modes;
122
123
124 /* Python-script modifier data */
125 typedef struct FMod_Python {
126         struct Text *script;            /* text buffer containing script to execute */
127         IDProperty *prop;                       /* ID-properties to provide 'custom' settings */
128 } FMod_Python;
129
130 /* Drivers -------------------------------------- */
131
132 /* Channel Driver (i.e. Drivers / Expressions) (driver)
133  *
134  * Channel Drivers are part of the dependency system, and are executed in addition to 
135  * normal user-defined animation. They take the animation result of some channel(s), and
136  * use that (optionally combined with its own F-Curve for modification of results) to define
137  * the value of some setting semi-procedurally.
138  *
139  * Drivers are stored as part of F-Curve data, so that the F-Curve's RNA-path settings (for storing
140  * what setting the driver will affect). The order in which they are stored defines the order that they're
141  * evaluated in. This order is set by the Depsgraph's sorting stuff. 
142  */
143 typedef struct ChannelDriver {
144                 /* primary target */
145         ID      *id;                    /* ID-block which owns the target */
146         char *rna_path;         /* target channel to use as driver value */
147         int array_index;        /* if applicable, the index of the RNA-array item to use as driver */
148         
149                 /* value cache (placed here for alignment reasons) */
150         float curval;           /* result of previous evaluation, for subtraction from result under certain circumstances */
151         
152                 /* secondary target (for rotational difference) */
153         ID      *id2;                   /* ID-block which owns the second target */
154         char *rna_path2;        /* second target channel to use as driver value */
155         int array_index2;       /* if applicable, the index of the RNA-array item to use as driver */
156                 
157                 /* general settings (placed here for alignment reasons) */
158         int type;                       /* type of driver */
159         int flag;                       /* settings of driver */
160         
161         float influence;        /* influence of driver on result */ // XXX to be implemented... this is like the constraint influence setting
162         
163                 /* settings for Python Drivers (PyDrivers) */
164         char expression[256]; /* python expression to execute (may call functions defined in an accessory file) */
165 } ChannelDriver;
166
167 /* driver type */
168 enum {
169                 /* channel drives channel */
170         DRIVER_TYPE_CHANNEL     = 0,
171                 /* py-expression used as driver */
172         DRIVER_TYPE_PYTHON,
173                 /* rotational difference (must use rotation channels only) */
174         DRIVER_TYPE_ROTDIFF,
175 } eDriver_Types;
176
177 /* driver flags */
178 enum {
179                 /* driver has invalid settings (internal flag)  */
180         DRIVER_FLAG_INVALID             = (1<<0),
181                 /* driver was disabled temporarily, so shouldn't be evaluated (set by user) */
182         DRIVER_FLAG_DISABLED    = (1<<1),
183                 /* driver needs recalculation (set by depsgraph) */
184         DRIVER_FLAG_RECALC              = (1<<2),
185                 /* driver does replace value, but overrides (for layering of animation over driver) */
186                 // TODO: is this necessary?
187         DRIVER_FLAG_LAYERING    = (1<<3),
188 } eDriver_Flags;
189
190 /* F-Curves -------------------------------------- */
191
192 /* FPoint (fpt)
193  *
194  * This is the bare-minimum data required storing motion samples. Should be more efficient
195  * than using BPoints, which contain a lot of other unnecessary data...
196  */
197 typedef struct FPoint {
198         float vec[2];           /* time + value */
199         int flag;                       /* selection info */
200         int pad;
201 } FPoint;
202
203 /* 'Function-Curve' - defines values over time for a given setting (fcu) */
204 typedef struct FCurve {
205         struct FCurve *next, *prev;
206         
207                 /* group */
208         bActionGroup *grp;              /* group that F-Curve belongs to */
209         
210                 /* driver settings */
211         ChannelDriver *driver;  /* only valid for drivers (i.e. stored in AnimData not Actions) */
212                 /* evaluation settings */
213         ListBase modifiers;             /* FCurve Modifiers */
214                 
215                 /* motion data */
216         BezTriple *bezt;                /* user-editable keyframes (array) */
217         FPoint *fpt;                    /* 'baked/imported' motion samples (array) */
218         int totvert;                    /* total number of points which define the curve (i.e. size of arrays in FPoints) */
219         
220                 /* value cache + settings */
221         float curval;                   /* value stored from last time curve was evaluated */
222         short flag;                             /* user-editable settings for this curve */
223         short extend;                   /* value-extending mode for this curve (does not cover  */
224         
225                 /* RNA - data link */
226         int array_index;                /* if applicable, the index of the RNA-array item to get */
227         char *rna_path;                 /* RNA-path to resolve data-access */
228 } FCurve;
229
230
231 /* user-editable flags/settings */
232 enum {
233                 /* curve/keyframes are visible in editor */
234         FCURVE_VISIBLE          = (1<<0),
235                 /* curve is selected for editing  */
236         FCURVE_SELECTED         = (1<<1),
237                 /* curve is active one */
238         FCURVE_ACTIVE           = (1<<2),
239                 /* keyframes (beztriples) cannot be edited */
240         FCURVE_PROTECTED        = (1<<3),
241                 /* fcurve will not be evaluated for the next round */
242         FCURVE_MUTED            = (1<<4),
243                 /* fcurve uses 'auto-handles', which stay horizontal... */
244         FCURVE_AUTO_HANDLES     = (1<<5),
245         
246                 /* skip evaluation, as RNA-path cannot be resolved (similar to muting, but cannot be set by user) */
247         FCURVE_DISABLED                 = (1<<10),
248                 /* curve can only have whole-number values (int or boolean types) */
249         FCURVE_INT_VALUES               = (1<<11),
250 } eFCurve_Flags;
251
252 /* extrapolation modes (only simple value 'extending') */
253 enum {
254         FCURVE_EXTRAPOLATE_CONSTANT     = 0,    /* just extend min/max keyframe value  */
255         FCURVE_EXTRAPOLATE_LINEAR,                      /* just extend gradient of segment between first segment keyframes */
256 } eFCurve_Extend;
257
258 /* ************************************************ */
259 /* 'Action' Datatypes */
260
261 /* NOTE: Although these are part of the Animation System,
262  * they are not stored here... see DNA_action_types.h instead
263  */
264
265  
266 /* ************************************************ */
267 /* Animation Reuse - i.e. users of Actions */
268
269 /* Retargetting ----------------------------------- */
270
271 /* Retargetting Pair
272  *
273  * Defines what parts of the paths should be remapped from 'abc' to 'xyz'.
274  * TODO:
275  *      - Regrex (possibly provided through PY, though having our own module might be faster)
276  *        would be important to have at some point. Current replacements are just simple
277  *        string matches...
278  */
279 typedef struct AnimMapPair {
280         char from[128];         /* part of path to bed replaced */
281         char to[128];           /* part of path to replace with */
282 } AnimMapPair;
283
284 /* Retargetting Information for Actions 
285  *
286  * This should only be used if it is strictly necessary (i.e. user will need to explictly 
287  * add this when they find that some channels do not match, or motion is not going to right 
288  * places). When executing an action, this will be checked to see if it provides any useful
289  * remaps for the given paths.
290  *
291  * NOTE: we currently don't store this in the Action itself, as that causes too many problems.
292  */
293 // FIXME: will this be too clumsy or slow? If we're using RNA paths anyway, we'll have to accept
294 // such consequences...
295 typedef struct AnimMapper {
296         struct AnimMapper *next, *prev;
297         
298         bAction *target;                /* target action */
299         ListBase mappings;              /* remapping table (bAnimMapPair) */
300 } AnimMapper;
301
302 /* ************************************************ */
303 /* NLA - Non-Linear Animation */
304 // TODO: the concepts here still need to be refined to solve any unresolved items
305
306 /* NLA Modifiers ---------------------------------- */
307
308 /* These differ from F-Curve modifiers, as although F-Curve modifiers also operate on a 
309  * per-channel basis too (in general), they are part of the animation data itself, which
310  * means that their effects are inherited by all of their users. In order to counteract this,
311  * the modifiers here should be used to provide variation to pre-created motions only. 
312  */
313
314 /* NLA Strips ------------------------------------- */
315
316 /* NLA Strip (strip)
317  *
318  * A NLA Strip is a container for the reuse of Action data, defining parameters
319  * to control the remapping of the Action data to some destination. Actions being
320  * referenced by NLA-Strips SHOULD-NOT be editable, unless they were created in such
321  * a way that results in very little mapping distortion (i.e. for layered animation only,
322  * opposed to prebuilt 'blocks' which are quickly dumped into the NLA for crappymatic machima-type
323  * stuff)
324  */
325 typedef struct NlaStrip {
326         struct NlaStrip *next, *prev;
327         
328         bAction *act;                           /* Action that is referenced by this strip */
329         AnimMapper *remap;                      /* Remapping info this strip (for tweaking correspondance of action with context) */
330         
331         ListBase modifiers;                     /* NLA Modifiers */     
332         
333         ListBase fcurves;                       /* F-Curves for controlling this strip's influence and timing */
334         float influence;                        /* Influence of strip */
335         float act_time;                         /* Current 'time' within action being used */
336         
337         float start, end;                       /* extents of the strip */
338         float actstart, actend;         /* range of the action to use */
339         
340         float   repeat;                         /* The number of times to repeat the action range (only when no F-Curves) */
341         float   scale;                          /* The amount the action range is scaled by (only when no F-Curves) */
342         
343         float blendin, blendout;        /* strip blending length (only used when there are no F-Curves) */      
344         int blendmode;                          /* strip blending mode */       
345         
346         int flag;                                       /* settings */
347         
348                 // umm... old unused cruft? 
349         int stride_axis;                        /* axis for stridebone stuff - 0=x, 1=y, 2=z */
350         int pad;
351         
352         float   actoffs;                        /* Offset within action, for cycles and striding (only set for ACT_USESTRIDE) */
353         float   stridelen;                      /* The stridelength (considered when flag & ACT_USESTRIDE) */
354         
355         char    stridechannel[32];      /* Instead of stridelen, it uses an action channel */
356         char    offs_bone[32];          /* if repeat, use this bone/channel for defining offset */
357 } NlaStrip;
358
359 /* NLA Strip Blending Mode */
360 enum {
361         NLASTRIPMODE_BLEND = 0,
362         NLASTRIPMODE_ADD,
363         NLASTRIPMODE_SUBTRACT,
364 } eActStrip_Mode;
365
366 /* NLA Strip Settings */
367 // TODO: check on which of these are still useful...
368 enum {
369         NLASTRIP_SELECT                 = (1<<0),
370         NLASTRIP_USESTRIDE              = (1<<1),
371         NLASTRIP_BLENDTONEXT    = (1<<2),       /* Not implemented. Is not used anywhere */
372         NLASTRIP_HOLDLASTFRAME  = (1<<3),
373         NLASTRIP_ACTIVE                 = (1<<4),
374         NLASTRIP_LOCK_ACTION    = (1<<5),
375         NLASTRIP_MUTE                   = (1<<6),
376         NLASTRIP_REVERSE                = (1<<7),       /* This has yet to be implemented. To indicate that a strip should be played backwards */
377         NLASTRIP_CYCLIC_USEX    = (1<<8),
378         NLASTRIP_CYCLIC_USEY    = (1<<9),
379         NLASTRIP_CYCLIC_USEZ    = (1<<10),
380         NLASTRIP_AUTO_BLENDS    = (1<<11),
381         NLASTRIP_TWEAK                  = (1<<12),      /* This strip is a tweaking strip (only set if owner track is a tweak track) */
382 } eActionStrip_Flag;
383
384 /* NLA Tracks ------------------------------------- */
385
386 /* NLA Track (nlt)
387  *
388  * A track groups a bunch of 'strips', which should form a continous set of 
389  * motion, on top of which other such groups can be layered. This should allow
390  * for animators to work in a non-destructive manner, layering tweaks, etc. over
391  * 'rough' blocks of their work.
392  */
393 typedef struct NlaTrack {
394         struct NlaTrack *next, *prev;
395         
396         ListBase strips;                /* bActionStrips in this track */
397         
398         int flag;                               /* settings for this track */
399         int index;                              /* index of the track in the stack (NOTE: not really useful, but we need a pad var anyways!) */
400         
401         char info[64];                  /* short user-description of this track */
402 } NlaTrack;
403
404 /* settings for track */
405 enum {
406                 /* track is the one that settings can be modified on (doesn't indicate 
407                  * that it's for 'tweaking' though) 
408                  */
409         NLATRACK_ACTIVE         = (1<<0),
410                 /* track is selected in UI for relevant editing operations */
411         NLATRACK_SELECTED       = (1<<1),
412                 /* track is not evaluated */
413         NLATRACK_MUTED          = (1<<2),
414                 /* track is the only one evaluated (must be used in conjunction with adt->flag) */
415         NLATRACK_SOLO           = (1<<3),
416                 /* track's settings (and strips) cannot be edited (to guard against unwanted changes) */
417         NLATRACK_PROTECTED      = (1<<4),
418                 /* strip is the 'last' one that should be evaluated, as the active action 
419                  * is being used to tweak the animation of the strips up to here 
420                  */
421         NLATRACK_TWEAK          = (1<<5),
422 } eNlaTrack_Flag;
423
424
425 /* ************************************ */
426 /* KeyingSet Datatypes */
427
428 /* Path for use in KeyingSet definitions (ksp) 
429  *
430  * Paths may be either specific (specifying the exact sub-ID
431  * dynamic data-block - such as PoseChannels - to act upon, ala
432  * Maya's 'Character Sets' and XSI's 'Marking Sets'), or they may
433  * be generic (using various placeholder template tags that will be
434  * replaced with appropriate information from the context). 
435  */
436 // TODO: how should templates work exactly? For now, we only implement the specific KeyingSets...
437 typedef struct KS_Path {
438         struct KS_Path *next, *prev;
439         
440                 /* absolute paths only */
441         ID *id;                                 /* ID block that keyframes are for */
442         char group[64];                 /* name of the group to add to */
443         
444                 /* all paths */
445         char *rna_path;                 /* dynamically (or statically in the case of predefined sets) path */
446         int array_index;                /* index that path affects */
447         
448         short flag;                             /* various settings, etc. */
449         short groupmode;                /* group naming (eKSP_Grouping) */
450 } KS_Path;
451
452 /* KS_Path->flag */
453 enum {
454                 /* entire array (not just the specified index) gets keyframed */
455         KSP_FLAG_WHOLE_ARRAY    = (1<<0),
456 } eKSP_Settings;
457
458 /* KS_Path->groupmode */
459 enum {
460                 /* path should be grouped using its own group-name */
461         KSP_GROUP_NAMED = 0,
462                 /* path should not be grouped at all */
463         KSP_GROUP_NONE,
464                 /* path should be grouped under an ActionGroup KeyingSet's name */
465         KSP_GROUP_KSNAME,
466 } eKSP_Grouping;
467
468 /* ---------------- */
469  
470 /* KeyingSet definition (ks)
471  *
472  * A KeyingSet defines a group of properties that should
473  * be keyframed together, providing a convenient way for animators
474  * to insert keyframes without resorting to Auto-Keyframing.
475  *
476  * A few 'generic' (non-absolute and dependant on templates) KeyingSets 
477  * are defined 'built-in' to facilitate easy animating for the casual
478  * animator without the need to add extra steps to the rigging process.
479  */
480 typedef struct KeyingSet {
481         struct KeyingSet *next, *prev;
482         
483         ListBase paths;                 /* (KS_Path) paths to keyframe to */
484         
485         char name[64];                  /* user-viewable name for KeyingSet (for menus, etc.) */
486         
487         int flag;                               /* settings for KeyingSet */
488         int keyingflag;                 /* settings to supply insertkey() with */
489 } KeyingSet;
490
491 /* KeyingSet settings */
492 enum {
493                 /* keyingset cannot be removed (and doesn't need to be freed) */
494         KEYINGSET_BUILTIN               = (1<<0),
495                 /* keyingset does not depend on context info (i.e. paths are absolute) */
496         KEYINGSET_ABSOLUTE              = (1<<1),
497 } eKS_Settings;
498
499 /* Flags for use by keyframe creation/deletion calls */
500 enum {
501         INSERTKEY_NEEDED        = (1<<0),       /* only insert keyframes where they're needed */
502         INSERTKEY_MATRIX        = (1<<1),       /* insert 'visual' keyframes where possible/needed */
503         INSERTKEY_FAST          = (1<<2),       /* don't recalculate handles,etc. after adding key */
504         INSERTKEY_FASTR         = (1<<3),       /* don't realloc mem (or increase count, as array has already been set out) */
505         INSERTKEY_REPLACE       = (1<<4),       /* only replace an existing keyframe (this overrides INSERTKEY_NEEDED) */
506 } eInsertKeyFlags;
507
508 /* ************************************************ */
509 /* Animation Data */
510
511 /* AnimOverride ------------------------------------- */
512
513 /* Animation Override (aor) 
514  *
515  * This is used to as temporary storage of values which have been changed by the user, but not
516  * yet keyframed (thus, would get overwritten by the animation system before the user had a chance
517  * to see the changes that were made). 
518  *
519  * It is probably not needed for overriding keyframed values in most cases, as those will only get evaluated
520  * on frame-change now. That situation may change in future.
521  */
522 typedef struct AnimOverride {
523         struct AnimOverride *next, *prev;
524         
525         char *rna_path;                 /* RNA-path to use to resolve data-access */
526         int array_index;                /* if applicable, the index of the RNA-array item to get */
527         
528         float value;                    /* value to override setting with */
529 } AnimOverride;
530
531 /* AnimData ------------------------------------- */
532
533 /* Animation data for some ID block (adt)
534  * 
535  * This block of data is used to provide all of the necessary animation data for a datablock.
536  * Currently, this data will not be reusable, as there shouldn't be any need to do so.
537  * 
538  * This information should be made available for most if not all ID-blocks, which should 
539  * enable all of its settings to be animatable locally. Animation from 'higher-up' ID-AnimData
540  * blocks may override local settings.
541  *
542  * This datablock should be placed immediately after the ID block where it is used, so that
543  * the code which retrieves this data can do so in an easier manner. See blenkernel/internal/anim_sys.c for details.
544  */
545 typedef struct AnimData {       
546                 /* active action - acts as the 'tweaking track' for the NLA */
547         bAction         *action;                
548                 /* remapping-info for active action - should only be used if needed 
549                  * (for 'foreign' actions that aren't working correctly) 
550                  */
551         AnimMapper      *remap;                 
552         
553                 /* nla-tracks */
554         ListBase        nla_tracks;
555         
556         /* 'drivers' for this ID-block's settings - FCurves, but are completely 
557          * separate from those for animation data 
558          */
559         ListBase        drivers;        /* standard user-created Drivers/Expressions (used as part of a rig) */
560         ListBase        overrides;      /* temp storage (AnimOverride) of values for settings that are animated (but the value hasn't been keyframed) */
561         
562                 /* settings for animation evaluation */
563         int flag;                       /* user-defined settings */
564         int recalc;                     /* depsgraph recalculation flags */             
565 } AnimData;
566
567 /* Animation Data settings (mostly for NLA) */
568 enum {
569                 /* only evaluate a single track in the NLA */
570         ADT_NLA_SOLO_TRACK              = (1<<0),
571                 /* don't use NLA */
572         ADT_NLA_EVAL_OFF                = (1<<1),
573                 /* don't execute drivers */
574         ADT_DRIVERS_DISABLED    = (1<<2),
575         
576                 /* drivers expanded in UI */
577         ADT_DRIVERS_COLLAPSED   = (1<<10),
578 } eAnimData_Flag;
579
580 /* Animation Data recalculation settings (to be set by depsgraph) */
581 enum {
582         ADT_RECALC_DRIVERS              = (1<<0),
583         ADT_RECALC_ANIM                 = (1<<1),
584         ADT_RECALC_ALL                  = (ADT_RECALC_DRIVERS|ADT_RECALC_ANIM),
585 } eAnimData_Recalc;
586
587 /* Base Struct for Anim ------------------------------------- */
588
589 /* Used for BKE_animdata_from_id() 
590  * All ID-datablocks which have their own 'local' AnimData
591  * should have the same arrangement in their structs.
592  */
593 typedef struct IdAdtTemplate {
594         ID id;
595         AnimData *adt;
596 } IdAdtTemplate;
597
598 /* ************************************************ */
599
600 #ifdef __cplusplus
601 };
602 #endif
603
604 #endif /* DNA_ANIM_TYPES_H */