Blender V2.61 - r43446

rna_nla.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Blender Foundation (2009), Joshua Leung
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00028 #include <stdlib.h>
00029 
00030 #include "RNA_define.h"
00031 
00032 #include "rna_internal.h"
00033 
00034 #include "DNA_anim_types.h"
00035 #include "DNA_action_types.h"
00036 #include "DNA_scene_types.h"
00037 
00038 #include "MEM_guardedalloc.h"
00039 
00040 #include "WM_api.h"
00041 #include "WM_types.h"
00042 
00043 #ifdef RNA_RUNTIME
00044 
00045 #include <stdio.h>
00046 #include <math.h>
00047 
00048 /* needed for some of the validation stuff... */
00049 #include "BKE_animsys.h"
00050 #include "BKE_nla.h"
00051 
00052 #include "ED_anim_api.h"
00053 
00054 /* temp constant defined for these funcs only... */
00055 #define NLASTRIP_MIN_LEN_THRESH     0.1f
00056 
00057 static void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value)
00058 {
00059     NlaStrip *data= (NlaStrip *)ptr->data;
00060     
00061     /* copy the name first */
00062     BLI_strncpy_utf8(data->name, value, sizeof(data->name));
00063     
00064     /* validate if there's enough info to do so */
00065     if (ptr->id.data) {
00066         AnimData *adt= BKE_animdata_from_id(ptr->id.data);
00067         BKE_nlastrip_validate_name(adt, data);
00068     }
00069 }
00070 
00071 static char *rna_NlaStrip_path(PointerRNA *ptr)
00072 {
00073     NlaStrip *strip= (NlaStrip *)ptr->data;
00074     AnimData *adt= BKE_animdata_from_id(ptr->id.data);
00075     
00076     /* if we're attached to AnimData, try to resolve path back to AnimData */
00077     if (adt) {
00078         NlaTrack *nlt;
00079         NlaStrip *nls;
00080         
00081         for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
00082             for (nls = nlt->strips.first; nls; nls = nls->next) {
00083                 if (nls == strip) {
00084                     // XXX but if we animate like this, the control will never work...
00085                     return BLI_sprintfN("animation_data.nla_tracks[\"%s\"].strips[\"%s\"]", nlt->name, strip->name);
00086                 }
00087             }
00088         }
00089     }
00090     
00091     /* no path */
00092     return "";
00093 }
00094 
00095 static void rna_NlaStrip_transform_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
00096 {
00097     NlaStrip *strip= (NlaStrip*)ptr->data;
00098 
00099     BKE_nlameta_flush_transforms(strip);
00100 }
00101 
00102 static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
00103 {
00104     NlaStrip *data= (NlaStrip*)ptr->data;
00105     
00106     /* clamp value to lie within valid limits 
00107      *  - cannot start past the end of the strip + some flexibility threshold
00108      *  - cannot start before the previous strip (if present) ends
00109      *      -> but if it was a transition, we could go up to the start of the strip + some flexibility threshold
00110      *      as long as we re-adjust the transition afterwards
00111      *  - minimum frame is -MAXFRAME so that we don't get clipping on frame 0
00112      */
00113     if (data->prev) {
00114         if (data->prev->type == NLASTRIP_TYPE_TRANSITION) {
00115             CLAMP(value, data->prev->start+NLASTRIP_MIN_LEN_THRESH, data->end-NLASTRIP_MIN_LEN_THRESH);
00116             
00117             /* readjust the transition to stick to the endpoints of the action-clips */
00118             data->prev->end= value;
00119         }
00120         else {
00121             CLAMP(value, data->prev->end, data->end-NLASTRIP_MIN_LEN_THRESH);
00122         }
00123     }
00124     else {
00125         CLAMP(value, MINAFRAME, data->end);
00126     }
00127     data->start= value;
00128 }
00129 
00130 static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
00131 {
00132     NlaStrip *data= (NlaStrip*)ptr->data;
00133     
00134     /* clamp value to lie within valid limits
00135      *  - must not have zero or negative length strip, so cannot start before the first frame 
00136      *    + some minimum-strip-length threshold
00137      *  - cannot end later than the start of the next strip (if present)
00138      *      -> but if it was a transition, we could go up to the start of the end - some flexibility threshold
00139      *      as long as we re-adjust the transition afterwards
00140      */
00141     if (data->next) {
00142         if (data->next->type == NLASTRIP_TYPE_TRANSITION) {
00143             CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, data->next->end-NLASTRIP_MIN_LEN_THRESH);
00144             
00145             /* readjust the transition to stick to the endpoints of the action-clips */
00146             data->next->start= value;
00147         }
00148         else {
00149             CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, data->next->start);
00150         }
00151     }
00152     else {
00153         CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, MAXFRAME);
00154     }
00155     data->end= value;
00156     
00157     
00158     /* calculate the lengths the strip and its action (if applicable) */
00159     if (data->type == NLASTRIP_TYPE_CLIP) {
00160         float len, actlen;
00161         
00162         len= data->end - data->start;
00163         actlen= data->actend - data->actstart;
00164         if (IS_EQF(actlen, 0.0f)) actlen= 1.0f;
00165         
00166         /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */
00167         data->scale= len / ((actlen) * data->repeat);
00168     }
00169 }
00170 
00171 static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
00172 {
00173     NlaStrip *data= (NlaStrip*)ptr->data;
00174     
00175     /* set scale value */
00176     CLAMP(value, 0.0001f, 1000.0f); /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
00177     data->scale= value;
00178     
00179     /* adjust the strip extents in response to this */
00180     BKE_nlastrip_recalculate_bounds(data);
00181 }
00182 
00183 static void rna_NlaStrip_repeat_set(PointerRNA *ptr, float value)
00184 {
00185     NlaStrip *data= (NlaStrip*)ptr->data;
00186     
00187     /* set repeat value */
00188     CLAMP(value, 0.01f, 1000.0f); /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
00189     data->repeat= value;
00190     
00191     /* adjust the strip extents in response to this */
00192     BKE_nlastrip_recalculate_bounds(data);
00193 }
00194 
00195 static void rna_NlaStrip_blend_in_set(PointerRNA *ptr, float value)
00196 {
00197     NlaStrip *data= (NlaStrip*)ptr->data;
00198     float len;
00199     
00200     /* blend-in is limited to the length of the strip, and also cannot overlap with blendout */
00201     len= (data->end - data->start) - data->blendout;
00202     CLAMP(value, 0, len);
00203     
00204     data->blendin= value;
00205 }
00206 
00207 static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value)
00208 {
00209     NlaStrip *data= (NlaStrip*)ptr->data;
00210     float len;
00211     
00212     /* blend-out is limited to the length of the strip */
00213     len= (data->end - data->start);
00214     CLAMP(value, 0, len);
00215     
00216     /* it also cannot overlap with blendin */
00217     if ((len - value) < data->blendin)
00218         value= len - data->blendin;
00219     
00220     data->blendout= value;
00221 }
00222 
00223 static int rna_NlaStrip_action_editable(PointerRNA *ptr)
00224 {
00225     NlaStrip *strip = (NlaStrip *)ptr->data;
00226     
00227     /* strip actions shouldn't be editable if NLA tweakmode is on */
00228     if (ptr->id.data) {
00229         AnimData *adt = BKE_animdata_from_id(ptr->id.data);
00230         
00231         if (adt) {
00232             /* active action is only editable when it is not a tweaking strip */
00233             if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact))
00234                 return 0;
00235         }
00236     }
00237     
00238     /* check for clues that strip probably shouldn't be used... */
00239     if (strip->flag & NLASTRIP_FLAG_TWEAKUSER)
00240         return 0;
00241         
00242     /* should be ok, though we may still miss some cases */
00243     return 1;
00244 }
00245 
00246 static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value)
00247 {
00248     NlaStrip *data= (NlaStrip*)ptr->data;
00249     
00250     /* prevent start frame from occurring after end of action */
00251     CLAMP(value, MINAFRAME, data->actend);
00252     data->actstart= value;
00253     
00254     /* adjust the strip extents in response to this */
00255     // TODO: should the strip be moved backwards instead as a special case?
00256     BKE_nlastrip_recalculate_bounds(data);
00257 }
00258 
00259 static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value)
00260 {
00261     NlaStrip *data= (NlaStrip*)ptr->data;
00262     
00263     /* prevent end frame from starting before start of action */
00264     CLAMP(value, data->actstart, MAXFRAME);
00265     data->actend= value;
00266     
00267     /* adjust the strip extents in response to this */
00268     BKE_nlastrip_recalculate_bounds(data);
00269 }
00270 
00271 static void rna_NlaStrip_animated_influence_set(PointerRNA *ptr, int value)
00272 {
00273     NlaStrip *data= (NlaStrip*)ptr->data;
00274     
00275     if (value) {
00276         /* set the flag, then make sure a curve for this exists */
00277         data->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
00278         BKE_nlastrip_validate_fcurves(data);
00279     }
00280     else
00281         data->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
00282 }
00283 
00284 static void rna_NlaStrip_animated_time_set(PointerRNA *ptr, int value)
00285 {
00286     NlaStrip *data= (NlaStrip*)ptr->data;
00287     
00288     if (value) {
00289         /* set the flag, then make sure a curve for this exists */
00290         data->flag |= NLASTRIP_FLAG_USR_TIME;
00291         BKE_nlastrip_validate_fcurves(data);
00292     }
00293     else
00294         data->flag &= ~NLASTRIP_FLAG_USR_TIME;
00295 }
00296 
00297 static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *reports, const char *UNUSED(name), int start, bAction *action)
00298 {
00299     NlaStrip *strip = add_nlastrip(action);
00300     
00301     if (strip == NULL) {
00302         BKE_reportf(reports, RPT_ERROR, "Unable to create new strip");
00303         return NULL;
00304     }
00305     
00306     strip->end += (start - strip->start);
00307     strip->start = start;
00308     
00309     if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) {
00310         BKE_reportf(reports, RPT_ERROR, "Unable to add strip. Track doesn't have any space to accommodate this new strip");
00311         free_nlastrip(NULL, strip);
00312         return NULL;
00313     }
00314     
00315     /* create dummy AnimData block so that BKE_nlastrip_validate_name() 
00316      * can be used to ensure a valid name, as we don't have one here...
00317      *  - only the nla_tracks list is needed there, which we aim to reverse engineer here...
00318      */
00319     {
00320         AnimData adt = {NULL};
00321         NlaTrack *nlt, *nlt_p;
00322         
00323         /* 'first' NLA track is found by going back up chain of given track's parents until we fall off */
00324         nlt_p = track; nlt = track;
00325         while ((nlt = nlt->prev) != NULL)
00326             nlt_p = nlt;
00327         adt.nla_tracks.first = nlt_p;
00328         
00329         /* do the same thing to find the last track */
00330         nlt_p = track; nlt = track;
00331         while ((nlt = nlt->next) != NULL)
00332             nlt_p = nlt;
00333         adt.nla_tracks.last = nlt_p;
00334         
00335         /* now we can just auto-name as usual */
00336         BKE_nlastrip_validate_name(&adt, strip);
00337     }
00338     
00339     WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_ADDED, NULL);
00340     
00341     return strip;
00342 }
00343 
00344 static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *reports, NlaStrip *strip)
00345 {
00346     if(BLI_findindex(&track->strips, strip) == -1) {
00347         BKE_reportf(reports, RPT_ERROR, "NLA's Strip '%s' not found in track '%s'", strip->name, track->name);
00348         return;
00349     }
00350     else {
00351         free_nlastrip(&track->strips, strip);
00352         WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_REMOVED, NULL);
00353     }
00354 }
00355 
00356 #else
00357 
00358 /* enum defines exported for rna_animation.c */
00359 EnumPropertyItem nla_mode_blend_items[] = {
00360     {NLASTRIP_MODE_REPLACE, "REPLACE", 0, "Replace", "Result strip replaces the accumulated results by amount specified by influence"},
00361     {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumulated results"},
00362     {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", "Weighted result of strip is removed from the accumulated results"},
00363     {NLASTRIP_MODE_MULTIPLY, "MULITPLY", 0, "Multiply", "Weighted result of strip is multiplied with the accumulated results"},
00364     {0, NULL, 0, NULL, NULL}};
00365 EnumPropertyItem nla_mode_extend_items[] = {
00366     {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents"},
00367     {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", "Hold the first frame if no previous strips in track, and always hold last frame"},
00368     {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame"},
00369     {0, NULL, 0, NULL, NULL}};
00370 
00371 static void rna_def_nlastrip(BlenderRNA *brna)
00372 {
00373     StructRNA *srna;
00374     PropertyRNA *prop;
00375     
00376         /* enum defs */
00377     static EnumPropertyItem prop_type_items[] = {
00378         {NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action"},
00379         {NLASTRIP_TYPE_TRANSITION, "TRANSITION", 0, "Transition", "NLA Strip 'transitions' between adjacent strips"},
00380         {NLASTRIP_TYPE_META, "META", 0, "Meta", "NLA Strip acts as a container for adjacent strips"},
00381         {NLASTRIP_TYPE_SOUND, "SOUND", 0, "Sound Clip", "NLA Strip representing a sound event for speakers"},
00382         {0, NULL, 0, NULL, NULL}};
00383     
00384     /* struct definition */
00385     srna= RNA_def_struct(brna, "NlaStrip", NULL);
00386     RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action");
00387     RNA_def_struct_path_func(srna, "rna_NlaStrip_path");
00388     RNA_def_struct_ui_icon(srna, ICON_NLA); // XXX
00389     
00390     /* name property */
00391     prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
00392     RNA_def_property_ui_text(prop, "Name", "");
00393     RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NlaStrip_name_set");
00394     RNA_def_struct_name_property(srna, prop);
00395     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00396     
00397     /* Enums */
00398     prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
00399     RNA_def_property_enum_sdna(prop, NULL, "type");
00400     RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable, since this is dangerous
00401     RNA_def_property_enum_items(prop, prop_type_items);
00402     RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip");
00403     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00404     
00405     prop= RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
00406     RNA_def_property_enum_sdna(prop, NULL, "extendmode");
00407     RNA_def_property_enum_items(prop, nla_mode_extend_items);
00408     RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents");
00409     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00410     
00411     prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
00412     RNA_def_property_enum_sdna(prop, NULL, "blendmode");
00413     RNA_def_property_enum_items(prop, nla_mode_blend_items);
00414     RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result");
00415     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00416     
00417     /* Strip extents */
00418     prop= RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_TIME);
00419     RNA_def_property_float_sdna(prop, NULL, "start");
00420     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_start_frame_set", NULL);
00421     RNA_def_property_ui_text(prop, "Start Frame", "");
00422     RNA_def_property_update(prop, 0, "rna_NlaStrip_transform_update");
00423     
00424     prop= RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_TIME);
00425     RNA_def_property_float_sdna(prop, NULL, "end");
00426     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL);
00427     RNA_def_property_ui_text(prop, "End Frame", "");
00428     RNA_def_property_update(prop, 0, "rna_NlaStrip_transform_update");
00429     
00430     /* Blending */
00431     prop= RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
00432     RNA_def_property_float_sdna(prop, NULL, "blendin");
00433     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_in_set", NULL);
00434     RNA_def_property_ui_text(prop, "Blend In", "Number of frames at start of strip to fade in influence");
00435     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00436     
00437     prop= RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
00438     RNA_def_property_float_sdna(prop, NULL, "blendout");
00439     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_out_set", NULL);
00440     RNA_def_property_ui_text(prop, "Blend Out", "");
00441     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00442     
00443     prop= RNA_def_property(srna, "use_auto_blend", PROP_BOOLEAN, PROP_NONE);
00444     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS);
00445     RNA_def_property_ui_text(prop, "Auto Blend In/Out", "Number of frames for Blending In/Out is automatically determined from overlapping strips");
00446     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00447     
00448     /* Action */
00449     prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
00450     RNA_def_property_pointer_sdna(prop, NULL, "act");
00451     RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll");
00452     RNA_def_property_flag(prop, PROP_EDITABLE); 
00453     RNA_def_property_editable_func(prop, "rna_NlaStrip_action_editable");
00454     RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip");
00455     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00456     
00457     /* Action extents */
00458     prop= RNA_def_property(srna, "action_frame_start", PROP_FLOAT, PROP_TIME);
00459     RNA_def_property_float_sdna(prop, NULL, "actstart");
00460     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_start_frame_set", NULL);
00461     RNA_def_property_ui_text(prop, "Action Start Frame", "");
00462     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00463     
00464     prop= RNA_def_property(srna, "action_frame_end", PROP_FLOAT, PROP_TIME);
00465     RNA_def_property_float_sdna(prop, NULL, "actend");
00466     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_end_frame_set", NULL);
00467     RNA_def_property_ui_text(prop, "Action End Frame", "");
00468     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00469     
00470     /* Action Reuse */
00471     prop= RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE);
00472     RNA_def_property_float_sdna(prop, NULL, "repeat"); 
00473     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_repeat_set", NULL);
00474     RNA_def_property_range(prop, 0.1f, 1000.0f); /* these limits have currently be chosen arbitarily, but could be extended (minimum should still be > 0 though) if needed... */
00475     RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range");
00476     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00477     
00478     prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
00479     RNA_def_property_float_sdna(prop, NULL, "scale"); 
00480     RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL);
00481     RNA_def_property_range(prop, 0.0001f, 1000.0f); /* these limits can be extended, but beyond this, we can get some crazy+annoying bugs due to numeric errors */
00482     RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action");
00483     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00484     
00485     /* Strip's F-Curves */
00486     prop= RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE);
00487     RNA_def_property_struct_type(prop, "FCurve");
00488     RNA_def_property_ui_text(prop, "F-Curves", "F-Curves for controlling the strip's influence and timing");
00489     
00490     /* Strip's F-Modifiers */
00491     prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
00492     RNA_def_property_struct_type(prop, "FModifier");
00493     RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action");
00494     
00495     /* Strip's Sub-Strips (for Meta-Strips) */
00496     prop= RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
00497     RNA_def_property_struct_type(prop, "NlaStrip");
00498     RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips that this strip acts as a container for (if it is of type Meta)");
00499     
00500     /* Settings - Values necessary for evaluation */
00501     prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
00502     RNA_def_property_range(prop, 0.0f, 1.0f);
00503     RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result");
00504     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00505     
00506     prop= RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME);
00507     RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate");
00508     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00509     
00510         // TODO: should the animated_influence/time settings be animatable themselves?
00511     prop= RNA_def_property(srna, "use_animated_influence", PROP_BOOLEAN, PROP_NONE);
00512     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
00513     RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_influence_set");
00514     RNA_def_property_ui_text(prop, "Animated Influence", "Influence setting is controlled by an F-Curve rather than automatically determined");
00515     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00516     
00517     prop= RNA_def_property(srna, "use_animated_time", PROP_BOOLEAN, PROP_NONE);
00518     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME);
00519     RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_time_set");
00520     RNA_def_property_ui_text(prop, "Animated Strip Time", "Strip time is controlled by an F-Curve rather than automatically determined");
00521     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00522     
00523     prop= RNA_def_property(srna, "use_animated_time_cyclic", PROP_BOOLEAN, PROP_NONE);
00524     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME_CYCLIC);
00525     RNA_def_property_ui_text(prop, "Cyclic Strip Time", "Cycle the animated time within the action start & end");
00526     RNA_def_property_update(prop, 0, "rna_NlaStrip_transform_update"); // is there a better update flag?
00527     
00528     /* settings */
00529     prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
00530     RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
00531     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_ACTIVE);
00532     RNA_def_property_ui_text(prop, "Active", "NLA Strip is active");
00533     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00534     
00535     prop= RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
00536     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SELECT);
00537     RNA_def_property_ui_text(prop, "Select", "NLA Strip is selected");
00538     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00539     
00540     prop= RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
00541     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_MUTED);
00542     RNA_def_property_ui_text(prop, "Muted", "NLA Strip is not evaluated");
00543     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00544     
00545     prop= RNA_def_property(srna, "use_reverse", PROP_BOOLEAN, PROP_NONE);
00546     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_REVERSE);
00547     RNA_def_property_ui_text(prop, "Reversed", "NLA Strip is played back in reverse order (only when timing is automatically determined)");
00548     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00549     
00550     // TODO: 
00551     // - sync length
00552 }
00553 
00554 static void rna_api_nlatrack_strips(BlenderRNA *brna, PropertyRNA *cprop)
00555 {
00556     StructRNA *srna;
00557     PropertyRNA *parm;
00558     FunctionRNA *func;
00559 
00560     RNA_def_property_srna(cprop, "NlaStrips");
00561     srna= RNA_def_struct(brna, "NlaStrips", NULL);
00562     RNA_def_struct_sdna(srna, "NlaTrack");
00563     RNA_def_struct_ui_text(srna, "Nla Strips", "Collection of Nla Strips");
00564 
00565     func = RNA_def_function(srna, "new", "rna_NlaStrip_new");
00566     RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
00567     RNA_def_function_ui_description(func, "Add a new Action-Clip strip to the track");
00568     parm= RNA_def_string(func, "name", "NlaStrip", 0, "", "Name for the NLA Strips");
00569     RNA_def_property_flag(parm, PROP_REQUIRED);
00570     parm = RNA_def_int(func, "start", 0, INT_MIN, INT_MAX, "Start Frame", "Start frame for this strip", INT_MIN, INT_MAX);
00571     RNA_def_property_flag(parm, PROP_REQUIRED);
00572     parm = RNA_def_pointer(func, "action", "Action", "", "Action to assign to this strip");
00573     RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
00574     /* return type */
00575     parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "New NLA Strip");
00576     RNA_def_function_return(func, parm);
00577 
00578     func = RNA_def_function(srna, "remove", "rna_NlaStrip_remove");
00579     RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
00580     RNA_def_function_ui_description(func, "Remove a NLA Strip");
00581     parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "NLA Strip to remove");
00582     RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
00583 }
00584 
00585 static void rna_def_nlatrack(BlenderRNA *brna)
00586 {
00587     StructRNA *srna;
00588     PropertyRNA *prop;
00589     
00590     srna= RNA_def_struct(brna, "NlaTrack", NULL);
00591     RNA_def_struct_ui_text(srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips");
00592     RNA_def_struct_ui_icon(srna, ICON_NLA);
00593     
00594     /* strips collection */
00595     prop= RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
00596     RNA_def_property_struct_type(prop, "NlaStrip");
00597     RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track");
00598 
00599     rna_api_nlatrack_strips(brna, prop);
00600 
00601     /* name property */
00602     prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
00603     RNA_def_property_ui_text(prop, "Name", "");
00604     RNA_def_struct_name_property(srna, prop);
00605     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00606     
00607     /* settings */
00608     prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
00609     RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
00610     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_ACTIVE);
00611     RNA_def_property_ui_text(prop, "Active", "NLA Track is active");
00612     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00613     
00614     prop= RNA_def_property(srna, "is_solo", PROP_BOOLEAN, PROP_NONE);
00615     RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
00616     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO);
00617     RNA_def_property_ui_text(prop, "Solo", "NLA Track is evaluated itself (i.e. active Action and all other NLA Tracks in the same AnimData block are disabled)");
00618     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00619     
00620     prop= RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
00621     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED);
00622     RNA_def_property_ui_text(prop, "Select", "NLA Track is selected");
00623     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00624     
00625     prop= RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
00626     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_MUTED);
00627     RNA_def_property_ui_text(prop, "Muted", "NLA Track is not evaluated");
00628     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00629 
00630     prop= RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
00631     RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED);
00632     RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked");
00633     RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
00634 }
00635 
00636 /* --------- */
00637 
00638 void RNA_def_nla(BlenderRNA *brna)
00639 {
00640     rna_def_nlatrack(brna);
00641     rna_def_nlastrip(brna);
00642 }
00643 
00644 
00645 #endif