Added an option "Cast Approximate" to control if a material should cast
[blender.git] / source / blender / blenkernel / intern / nla.c
index c41c4ae78e43c57708b4c991980d6c099820e658..2af9159f70f23226d5451489b9c656db37a5ff00 100644 (file)
@@ -219,6 +219,9 @@ void copy_nladata (ListBase *dst, ListBase *src)
        if ELEM(NULL, dst, src)
                return;
                
+       /* clear out the destination list first for precautions... */
+       dst->first= dst->last= NULL;
+               
        /* copy each NLA-track, one at a time */
        for (nlt= src->first; nlt; nlt= nlt->next) {
                /* make a copy, and add the copy to the destination list */
@@ -291,7 +294,7 @@ NlaStrip *add_nlastrip (bAction *act)
        /* determine initial range 
         *      - strip length cannot be 0... ever...
         */
-       calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
+       calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
        
        strip->start = strip->actstart;
        strip->end = (IS_EQ(strip->actstart, strip->actend)) ?  (strip->actstart + 1.0f): (strip->actend);
@@ -366,14 +369,7 @@ static float nlastrip_get_frame_actionclip (NlaStrip *strip, float cframe, short
                        return strip->end - scale*(cframe - strip->actstart);
                }
                else if (mode == NLATIME_CONVERT_UNMAP) {
-                       int repeatsNum = (int)((cframe - strip->start) / (actlength * scale));
-                       
-                       /* this method doesn't clip the values to lie within the action range only 
-                        *      - the '(repeatsNum * actlength * scale)' compensates for the fmod(...)
-                        *      - the fmod(...) works in the same way as for eval 
-                        */
-                       return strip->actend - (repeatsNum * actlength * scale) 
-                                       - (fmod(cframe - strip->start, actlength*scale) / scale);
+                       return strip->actend - (strip->end - cframe) / scale;   
                }
                else /* if (mode == NLATIME_CONVERT_EVAL) */{
                        if (IS_EQ(cframe, strip->end) && IS_EQ(strip->repeat, ((int)strip->repeat))) {
@@ -396,14 +392,7 @@ static float nlastrip_get_frame_actionclip (NlaStrip *strip, float cframe, short
                        return strip->start + scale*(cframe - strip->actstart);
                }
                else if (mode == NLATIME_CONVERT_UNMAP) {
-                       int repeatsNum = (int)((cframe - strip->start) / (actlength * scale));
-                       
-                       /* this method doesn't clip the values to lie within the action range only 
-                        *      - the '(repeatsNum * actlength * scale)' compensates for the fmod(...)
-                        *      - the fmod(...) works in the same way as for eval 
-                        */
-                       return strip->actstart + (repeatsNum * actlength * scale) 
-                                       + (fmod(cframe - strip->start, actlength*scale) / scale);
+                       return strip->actstart + (cframe - strip->start) / scale;
                }
                else /* if (mode == NLATIME_CONVERT_EVAL) */{
                        if (IS_EQ(cframe, strip->end) && IS_EQ(strip->repeat, ((int)strip->repeat))) {
@@ -1046,9 +1035,34 @@ short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max)
        return 1;
 }
 
+/* Recalculate the start and end frames for the current strip, after changing
+ * the extents of the action or the mapping (repeats or scale factor) info
+ */
+void BKE_nlastrip_recalculate_bounds (NlaStrip *strip)
+{
+       float actlen, mapping;
+       
+       /* sanity checks
+        *      - must have a strip
+        *      - can only be done for action clips
+        */
+       if ((strip == NULL) || (strip->type != NLASTRIP_TYPE_CLIP))
+               return;
+               
+       /* calculate new length factors */
+       actlen= strip->actend - strip->actstart;
+       if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
+       
+       mapping= strip->scale * strip->repeat;
+       
+       /* adjust endpoint of strip in response to this */
+       if (IS_EQ(mapping, 0.0f) == 0)
+               strip->end = (actlen * mapping) + strip->start;
+}
+
 /* Is the given NLA-strip the first one to occur for the given AnimData block */
 // TODO: make this an api method if necesary, but need to add prefix first
-short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
+static short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
 {
        NlaTrack *nlt;
        NlaStrip *ns;