merge with 2.5 (not trunk, last merge message said that on accident) at r22252
[blender.git] / source / blender / makesrna / intern / rna_nla.c
index 4b5c14aab82a893adf795f9af0fce95789ace2f8..a9b289f314bcd2a7595d02e503d926ca97aaeb2a 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id$
+ * $Id: rna_nla.c 21537 2009-07-11 22:22:53Z gsrb3d $
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
 #include <stdio.h>
 #include <math.h>
 
+/* needed for some of the validation stuff... */
+#include "BKE_animsys.h"
+#include "BKE_nla.h"
+
+/* temp constant defined for these funcs only... */
+#define NLASTRIP_MIN_LEN_THRESH        0.1f
+
+void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value)
+{
+       NlaStrip *data= (NlaStrip *)ptr->data;
+       
+       /* copy the name first */
+       BLI_strncpy(data->name, value, sizeof(data->name));
+       
+       /* validate if there's enough info to do so */
+       if (ptr->id.data) {
+               AnimData *adt= BKE_animdata_from_id(ptr->id.data);
+               BKE_nlastrip_validate_name(adt, data);
+       }
+}
+
+
 static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
 {
        NlaStrip *data= (NlaStrip*)ptr->data;
        
        /* clamp value to lie within valid limits 
         *      - cannot start past the end of the strip + some flexibility threshold
-        *      - cannot start before the previous strip (if present) ends 
+        *      - cannot start before the previous strip (if present) ends
+        *              -> but if it was a transition, we could go up to the start of the strip + some flexibility threshold
+        *              as long as we re-adjust the transition afterwards
         *      - minimum frame is -MAXFRAME so that we don't get clipping on frame 0
         */
        if (data->prev) {
-               CLAMP(value, data->prev->end, data->end-0.1f);
+               if (data->prev->type == NLASTRIP_TYPE_TRANSITION) {
+                       CLAMP(value, data->prev->start+NLASTRIP_MIN_LEN_THRESH, data->end-NLASTRIP_MIN_LEN_THRESH);
+                       
+                       /* readjust the transition to stick to the endpoints of the action-clips */
+                       data->prev->end= value;
+               }
+               else {
+                       CLAMP(value, data->prev->end, data->end-NLASTRIP_MIN_LEN_THRESH);
+               }
        }
        else {
-               CLAMP(value, -MAXFRAME, data->end);
+               CLAMP(value, MINAFRAME, data->end);
        }
        data->start= value;
 }
@@ -61,28 +93,42 @@ static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
 static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
 {
        NlaStrip *data= (NlaStrip*)ptr->data;
-       float len, actlen;
        
        /* clamp value to lie within valid limits
         *      - must not have zero or negative length strip, so cannot start before the first frame 
         *        + some minimum-strip-length threshold
         *      - cannot end later than the start of the next strip (if present)
+        *              -> but if it was a transition, we could go up to the start of the end - some flexibility threshold
+        *              as long as we re-adjust the transition afterwards
         */
        if (data->next) {
-               CLAMP(value, data->start+0.1f, data->next->start);
+               if (data->next->type == NLASTRIP_TYPE_TRANSITION) {
+                       CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, data->next->end-NLASTRIP_MIN_LEN_THRESH);
+                       
+                       /* readjust the transition to stick to the endpoints of the action-clips */
+                       data->next->start= value;
+               }
+               else {
+                       CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, data->next->start);
+               }
        }
        else {
-               CLAMP(value, data->start+0.1f, MAXFRAME);
+               CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, MAXFRAME);
        }
        data->end= value;
        
-       /* calculate the lengths the strip and its action (if applicable) */
-       len= data->end - data->start;
-       actlen= data->actend - data->actstart;
-       if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
        
-       /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */
-       data->scale= len / ((actlen) * data->repeat);
+       /* calculate the lengths the strip and its action (if applicable) */
+       if (data->type == NLASTRIP_TYPE_CLIP) {
+               float len, actlen;
+               
+               len= data->end - data->start;
+               actlen= data->actend - data->actstart;
+               if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
+               
+               /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */
+               data->scale= len / ((actlen) * data->repeat);
+       }
 }
 
 static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
@@ -106,6 +152,27 @@ static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
                printf("NlaStrip Set Scale Error (in RNA): Scale = %0.4f, Repeat = %0.4f \n", data->scale, data->repeat);
 }
 
+static void rna_NlaStrip_repeat_set(PointerRNA *ptr, float value)
+{
+       NlaStrip *data= (NlaStrip*)ptr->data;
+       float actlen, mapping;
+       
+       /* set scale value */
+       CLAMP(value, 0.01f, 1000.0f); /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
+       data->repeat= value;
+       
+       /* calculate existing factors */
+       actlen= data->actend - data->actstart;
+       if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
+       mapping= data->scale * data->repeat;
+       
+       /* adjust endpoint of strip in response to this */
+       if (IS_EQ(mapping, 0.0f) == 0)
+               data->end = (actlen * mapping) + data->start; 
+       else
+               printf("NlaStrip Set Repeat Error (in RNA): Scale = %0.4f, Repeat = %0.4f \n", data->scale, data->repeat);
+}
+
 static void rna_NlaStrip_blend_in_set(PointerRNA *ptr, float value)
 {
        NlaStrip *data= (NlaStrip*)ptr->data;
@@ -137,7 +204,7 @@ static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value)
 static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value)
 {
        NlaStrip *data= (NlaStrip*)ptr->data;
-       CLAMP(value, -MAXFRAME, data->actend);
+       CLAMP(value, MINAFRAME, data->actend);
        data->actstart= value;
 }
 
@@ -148,8 +215,47 @@ static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value)
        data->actend= value;
 }
 
+static void rna_NlaStrip_animated_influence_set(PointerRNA *ptr, int value)
+{
+       NlaStrip *data= (NlaStrip*)ptr->data;
+       
+       if (value) {
+               /* set the flag, then make sure a curve for this exists */
+               data->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+               BKE_nlastrip_validate_fcurves(data);
+       }
+       else
+               data->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
+}
+
+static void rna_NlaStrip_animated_time_set(PointerRNA *ptr, int value)
+{
+       NlaStrip *data= (NlaStrip*)ptr->data;
+       
+       if (value) {
+               /* set the flag, then make sure a curve for this exists */
+               data->flag |= NLASTRIP_FLAG_USR_TIME;
+               BKE_nlastrip_validate_fcurves(data);
+       }
+       else
+               data->flag &= ~NLASTRIP_FLAG_USR_TIME;
+}
+
 #else
 
+/* enum defines exported for rna_animation.c */
+EnumPropertyItem nla_mode_blend_items[] = {
+       {NLASTRIP_MODE_REPLACE, "REPLACE", 0, "Replace", "Result strip replaces the accumulated results by amount specified by influence."},
+       {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumlated results."},
+       {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", "Weighted result of strip is removed from the accumlated results."},
+       {NLASTRIP_MODE_MULTIPLY, "MULITPLY", 0, "Multiply", "Weighted result of strip is multiplied with the accumlated results."},
+       {0, NULL, 0, NULL, NULL}};
+EnumPropertyItem nla_mode_extend_items[] = {
+       {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents."},
+       {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", "Hold the first frame if no previous strips in track, and always hold last frame."},
+       {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."},
+       {0, NULL, 0, NULL, NULL}};
+
 void rna_def_nlastrip(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -157,40 +263,37 @@ void rna_def_nlastrip(BlenderRNA *brna)
        
                /* enum defs */
        static EnumPropertyItem prop_type_items[] = {
-               {NLASTRIP_TYPE_CLIP, "CLIP", "Action Clip", "NLA Strip references some Action."},
-               {NLASTRIP_TYPE_TRANSITION, "TRANSITION", "Transition", "NLA Strip 'transitions' between adjacent strips."},
-               {0, NULL, NULL, NULL}};
-       static EnumPropertyItem prop_mode_blend_items[] = {
-               {NLASTRIP_MODE_BLEND, "BLEND", "Blend", "Results of strip and accumulated results are combined in ratio governed by influence."},
-               {NLASTRIP_MODE_ADD, "ADD", "Add", "Weighted result of strip is added to the accumlated results."},
-               {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", "Subtract", "Weighted result of strip is removed from the accumlated results."},
-               {NLASTRIP_MODE_MULTIPLY, "MULITPLY", "Multiply", "Weighted result of strip is multiplied with the accumlated results."},
-               {0, NULL, NULL, NULL}};
-       static EnumPropertyItem prop_mode_extend_items[] = {
-               {NLASTRIP_EXTEND_NOTHING, "NOTHING", "Nothing", "Strip has no influence past its extents."},
-               {NLASTRIP_EXTEND_HOLD, "HOLD", "Hold", "Hold the first frame if no previous strips in track, and always hold last frame."},
-               {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", "Hold Forward", "Only hold last frame."},
-               {0, NULL, NULL, NULL}};
+               {NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action."},
+               {NLASTRIP_TYPE_TRANSITION, "TRANSITION", 0, "Transition", "NLA Strip 'transitions' between adjacent strips."},
+               {NLASTRIP_TYPE_META, "META", 0, "Meta", "NLA Strip acts as a container for adjacent strips."},
+               {0, NULL, 0, NULL, NULL}};
        
        /* struct definition */
        srna= RNA_def_struct(brna, "NlaStrip", NULL);
        RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action.");
        RNA_def_struct_ui_icon(srna, ICON_NLA); // XXX
        
+       /* name property */
+       prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Name", "");
+       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NlaStrip_name_set");
+       RNA_def_struct_name_property(srna, prop);
+       
        /* Enums */
        prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "type");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable, since this is dangerous
        RNA_def_property_enum_items(prop, prop_type_items);
        RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip.");
        
        prop= RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "extendmode");
-       RNA_def_property_enum_items(prop, prop_mode_extend_items);
+       RNA_def_property_enum_items(prop, nla_mode_extend_items);
        RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents.");
        
        prop= RNA_def_property(srna, "blending", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "blendmode");
-       RNA_def_property_enum_items(prop, prop_mode_blend_items);
+       RNA_def_property_enum_items(prop, nla_mode_blend_items);
        RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result.");
        
        /* Strip extents */
@@ -238,8 +341,9 @@ void rna_def_nlastrip(BlenderRNA *brna)
        /* Action Reuse */
        prop= RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "repeat"); 
-       RNA_def_property_range(prop, 1.0f, 1000.0f); /* these limits have currently be chosen arbitarily, but could be extended (minimum should still be > 0 though) if needed... */
-       RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the ");
+       RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_repeat_set", NULL);
+       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... */
+       RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range.");
        
        prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "scale"); 
@@ -247,13 +351,21 @@ void rna_def_nlastrip(BlenderRNA *brna)
        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 */
        RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action.");
        
-       // TODO: strip's F-Curves?
+       /* Strip's F-Curves */
+       prop= RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_struct_type(prop, "FCurve");
+       RNA_def_property_ui_text(prop, "F-Curves", "F-Curves for controlling the strip's influence and timing.");
        
        /* Strip's F-Modifiers */
        prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_struct_type(prop, "FModifier");
        RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action.");
        
+       /* Strip's Sub-Strips (for Meta-Strips) */
+       prop= RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_struct_type(prop, "NlaStrip");
+       RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips that this strip acts as a container for (if it is of type Meta).");
+       
        /* Settings - Values necessary for evaluation */
        prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -262,14 +374,15 @@ void rna_def_nlastrip(BlenderRNA *brna)
        prop= RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_NONE);
        RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate.");
        
+               // TODO: should the animated_influence/time settings be animatable themselves?
        prop= RNA_def_property(srna, "animated_influence", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable
        RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
+       RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_influence_set");
        RNA_def_property_ui_text(prop, "Animated Influence", "Influence setting is controlled by an F-Curve rather than automatically determined.");
        
        prop= RNA_def_property(srna, "animated_time", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME);
+       RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_time_set");
        RNA_def_property_ui_text(prop, "Animated Strip Time", "Strip time is controlled by an F-Curve rather than automatically determined.");
        
        /* settings */