Added an option "Cast Approximate" to control if a material should cast
[blender.git] / source / blender / blenkernel / intern / nla.c
index 1871ec006f4e3e3864ac7e8de88d1960c5e99b51..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))) {
@@ -993,6 +982,28 @@ NlaStrip *BKE_nlastrip_find_active (NlaTrack *nlt)
        return NULL;
 }
 
+/* Make the given NLA-Strip the active one within the given block */
+void BKE_nlastrip_set_active (AnimData *adt, NlaStrip *strip)
+{
+       NlaTrack *nlt;
+       NlaStrip *nls;
+       
+       /* sanity checks */
+       if (adt == NULL)
+               return;
+       
+       /* loop over tracks, deactivating*/
+       for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
+               for (nls= nlt->strips.first; nls; nls= nls->next)  {
+                       if (nls != strip)
+                               nls->flag &= ~NLASTRIP_FLAG_ACTIVE;
+                       else
+                               nls->flag |= NLASTRIP_FLAG_ACTIVE;
+               }
+       }
+}
+
+
 /* Does the given NLA-strip fall within the given bounds (times)? */
 short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max)
 {
@@ -1024,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;
@@ -1403,6 +1439,9 @@ void BKE_nla_action_pushdown (AnimData *adt)
                        // FIXME: this needs to be more automated, since user can rearrange strips
                        strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD;
                }
+               
+               /* make strip the active one... */
+               BKE_nlastrip_set_active(adt, strip);
        }
 }