Revision: 21185
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21185
Author:   aligorith
Date:     2009-06-27 14:35:11 +0200 (Sat, 27 Jun 2009)

Log Message:
-----------
NLA SoC: Recoded the strip<->global time conversion code 

* Strip evaluation now takes into account repeats
* Increasing the number of repeats lengthens the strip, while decreasing the 
number of repeats does the opposite.

TODO:
- inverse correction doesn't take into account repeats != 1, so tweaking strips 
with repeats is currently not recommended!

Modified Paths:
--------------
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
    branches/soc-2009-aligorith/source/blender/makesrna/intern/rna_nla.c

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c  
2009-06-27 11:57:50 UTC (rev 21184)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c  
2009-06-27 12:35:11 UTC (rev 21185)
@@ -331,7 +331,7 @@
  */
 static float nlastrip_get_frame_actionclip (NlaStrip *strip, float cframe, 
short invert)
 {
-       float length, actlength, repeat, scale;
+       float actlength, repeat, scale;
        
        /* get number of repeats */
        if (IS_EQ(strip->repeat, 0.0f)) strip->repeat = 1.0f;
@@ -345,24 +345,46 @@
        actlength = strip->actend - strip->actstart;
        if (IS_EQ(actlength, 0.0f)) actlength = 1.0f;
        
-       /* length of strip */
-       length= actlength * scale * repeat;
-       if (IS_EQ(length, 0.0f)) length= strip->end - strip->start;
-       
        /* reversed = play strip backwards */
        if (strip->flag & NLASTRIP_FLAG_REVERSE) {
                /* invert = convert action-strip time to global time */
                if (invert)
-                       return length*(strip->actend - 
cframe)/(repeat*actlength) + strip->start;
-               else
-                       return strip->actend - repeat*actlength*(cframe - 
strip->start)/length;
+                       return scale*(strip->actend - cframe) + strip->start; 
// FIXME: this doesn't work for multiple repeats yet
+               else {
+                       if (IS_EQ(cframe, strip->end) && IS_EQ(strip->repeat, 
((int)strip->repeat))) {
+                               /* this case prevents the motion snapping back 
to the first frame at the end of the strip 
+                                * by catching the case where repeats is a 
whole number, which means that the end of the strip
+                                * could also be interpreted as the end of the 
start of a repeat
+                                */
+                               return strip->actstart;
+                       }
+                       else {
+                               /* - the 'fmod(..., actlength*scale)' is needed 
to get the repeats working
+                                * - the '/ scale' is needed to ensure that 
scaling influences the timing within the repeat
+                                */
+                               return strip->actend - fmod(cframe - 
strip->start, actlength*scale) / scale; 
+                       }
+               }
        }
        else {
                /* invert = convert action-strip time to global time */
                if (invert)
-                       return length*(cframe - 
strip->actstart)/(repeat*actlength) + strip->start;
-               else
-                       return repeat*actlength*(cframe - strip->start)/length 
+ strip->actstart;
+                       return scale*(cframe - strip->actstart) + strip->start; 
// FIXME: this doesn't work for mutiple repeats yet
+               else {
+                       if (IS_EQ(cframe, strip->end) && IS_EQ(strip->repeat, 
((int)strip->repeat))) {
+                               /* this case prevents the motion snapping back 
to the first frame at the end of the strip 
+                                * by catching the case where repeats is a 
whole number, which means that the end of the strip
+                                * could also be interpreted as the end of the 
start of a repeat
+                                */
+                               return strip->actend;
+                       }
+                       else {
+                               /* - the 'fmod(..., actlength*scale)' is needed 
to get the repeats working
+                                * - the '/ scale' is needed to ensure that 
scaling influences the timing within the repeat
+                                */
+                               return strip->actstart + fmod(cframe - 
strip->start, actlength*scale) / scale; 
+                       }
+               }
        }
 }
 

Modified: branches/soc-2009-aligorith/source/blender/makesrna/intern/rna_nla.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/makesrna/intern/rna_nla.c        
2009-06-27 11:57:50 UTC (rev 21184)
+++ branches/soc-2009-aligorith/source/blender/makesrna/intern/rna_nla.c        
2009-06-27 12:35:11 UTC (rev 21185)
@@ -133,6 +133,27 @@
                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;
@@ -265,7 +286,8 @@
        /* 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_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 
");
        
        prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to