NLA SoC: NLA-Evaluation Bugfixes
[blender.git] / source / blender / blenkernel / intern / nla.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung (full recode)
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stdlib.h>
31 #include <stddef.h>
32 #include <stdio.h>
33 #include <math.h>
34 #include <float.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39
40 #include "DNA_anim_types.h"
41 #include "DNA_action_types.h"
42
43 #include "BKE_animsys.h"
44 #include "BKE_action.h"
45 #include "BKE_fcurve.h"
46 #include "BKE_nla.h"
47 #include "BKE_blender.h"
48 #include "BKE_library.h"
49 #include "BKE_object.h"
50 #include "BKE_utildefines.h"
51
52
53 #ifdef HAVE_CONFIG_H
54 #include <config.h>
55 #endif
56
57
58 /* *************************************************** */
59 /* Data Management */
60
61 /* Freeing ------------------------------------------- */
62
63 /* Remove the given NLA strip from the NLA track it occupies, free the strip's data,
64  * and the strip itself. 
65  */
66 // TODO: with things like transitions, should these get freed too? Maybe better as a UI tool
67 void free_nlastrip (ListBase *strips, NlaStrip *strip)
68 {
69         FModifier *fcm, *fmn;
70         
71         /* sanity checks */
72         if (strip == NULL)
73                 return;
74                 
75         /* remove reference to action */
76         if (strip->act)
77                 strip->act->id.us--;
78                 
79         /* free remapping info */
80         //if (strip->remap)
81         //      BKE_animremap_free();
82         
83         /* free own F-Curves */
84         free_fcurves(&strip->fcurves);
85         
86         /* free F-Modifiers */
87         for (fcm= strip->modifiers.first; fcm; fcm= fmn) {
88                 fmn= fcm->next;
89                 
90                 BLI_remlink(&strip->modifiers, fcm);
91                 fcurve_remove_modifier(NULL, fcm);
92         }
93         
94         /* free the strip itself */
95         if (strips)
96                 BLI_freelinkN(strips, strip);
97         else
98                 MEM_freeN(strip);
99 }
100
101 /* Remove the given NLA track from the set of NLA tracks, free the track's data,
102  * and the track itself.
103  */
104 void free_nlatrack (ListBase *tracks, NlaTrack *nlt)
105 {
106         NlaStrip *strip, *stripn;
107         
108         /* sanity checks */
109         if (nlt == NULL)
110                 return;
111                 
112         /* free strips */
113         for (strip= nlt->strips.first; strip; strip= stripn) {
114                 stripn= strip->next;
115                 free_nlastrip(&nlt->strips, strip);
116         }
117         
118         /* free NLA track itself now */
119         if (tracks)
120                 BLI_freelinkN(tracks, nlt);
121         else
122                 MEM_freeN(nlt);
123 }
124
125 /* Free the elements of type NLA Tracks provided in the given list, but do not free
126  * the list itself since that is not free-standing
127  */
128 void free_nladata (ListBase *tracks)
129 {
130         NlaTrack *nlt, *nltn;
131         
132         /* sanity checks */
133         if ELEM(NULL, tracks, tracks->first)
134                 return;
135                 
136         /* free tracks one by one */
137         for (nlt= tracks->first; nlt; nlt= nltn) {
138                 nltn= nlt->next;
139                 free_nlatrack(tracks, nlt);
140         }
141         
142         /* clear the list's pointers to be safe */
143         tracks->first= tracks->last= NULL;
144 }
145
146 /* Copying ------------------------------------------- */
147
148 /* Copy NLA strip */
149 NlaStrip *copy_nlastrip (NlaStrip *strip)
150 {
151         NlaStrip *strip_d;
152         
153         /* sanity check */
154         if (strip == NULL)
155                 return NULL;
156                 
157         /* make a copy */
158         strip_d= MEM_dupallocN(strip);
159         strip_d->next= strip_d->prev= NULL;
160         
161         /* increase user-count of action */
162         if (strip_d->act)
163                 strip_d->act->id.us++;
164                 
165         /* copy F-Curves and modifiers */
166         copy_fcurves(&strip_d->fcurves, &strip->fcurves);
167         fcurve_copy_modifiers(&strip_d->modifiers, &strip->modifiers);
168         
169         /* return the strip */
170         return strip_d;
171 }
172
173 /* Copy NLA Track */
174 NlaTrack *copy_nlatrack (NlaTrack *nlt)
175 {
176         NlaStrip *strip, *strip_d;
177         NlaTrack *nlt_d;
178         
179         /* sanity check */
180         if (nlt == NULL)
181                 return NULL;
182                 
183         /* make a copy */
184         nlt_d= MEM_dupallocN(nlt);
185         nlt_d->next= nlt_d->prev= NULL;
186         
187         /* make a copy of all the strips, one at a time */
188         nlt_d->strips.first= nlt_d->strips.last= NULL;
189         
190         for (strip= nlt->strips.first; strip; strip= strip->next) {
191                 strip_d= copy_nlastrip(strip);
192                 BLI_addtail(&nlt_d->strips, strip_d);
193         }
194         
195         /* return the copy */
196         return nlt_d;
197 }
198
199 /* Copy all NLA data */
200 void copy_nladata (ListBase *dst, ListBase *src)
201 {
202         NlaTrack *nlt, *nlt_d;
203         
204         /* sanity checks */
205         if ELEM(NULL, dst, src)
206                 return;
207                 
208         /* copy each NLA-track, one at a time */
209         for (nlt= src->first; nlt; nlt= nlt->next) {
210                 /* make a copy, and add the copy to the destination list */
211                 nlt_d= copy_nlatrack(nlt);
212                 BLI_addtail(dst, nlt_d);
213         }
214 }
215
216 /* Adding ------------------------------------------- */
217
218 /* Add a NLA Track to the given AnimData */
219 NlaTrack *add_nlatrack (AnimData *adt)
220 {
221         NlaTrack *nlt;
222         
223         /* sanity checks */
224         if (adt == NULL)
225                 return NULL;
226                 
227         /* allocate new track */
228         nlt= MEM_callocN(sizeof(NlaTrack), "NlaTrack");
229         
230         /* set settings requiring the track to not be part of the stack yet */
231         nlt->flag = NLATRACK_SELECTED;
232         nlt->index= BLI_countlist(&adt->nla_tracks);
233         
234         /* add track to stack, and make it the active one */
235         BLI_addtail(&adt->nla_tracks, nlt);
236         BKE_nlatrack_set_active(&adt->nla_tracks, nlt);
237         
238         /* must have unique name, but we need to seed this */
239         sprintf(nlt->name, "NlaTrack");
240         BLI_uniquename(&adt->nla_tracks, nlt, "NlaTrack", '.', offsetof(NlaTrack, name), 64);
241         
242         /* return the new track */
243         return nlt;
244 }
245
246 /* Add a NLA Strip referencing the given Action */
247 NlaStrip *add_nlastrip (bAction *act)
248 {
249         NlaStrip *strip;
250         
251         /* sanity checks */
252         if (act == NULL)
253                 return NULL;
254                 
255         /* allocate new strip */
256         strip= MEM_callocN(sizeof(NlaStrip), "NlaStrip");
257         
258         /* generic settings 
259          *      - selected flag to highlight this to the user
260          *      - auto-blends to ensure that blend in/out values are automatically 
261          *        determined by overlaps of strips
262          *      - (XXX) synchronisation of strip-length in accordance with changes to action-length
263          *        is not done though, since this should only really happens in editmode for strips now
264          *        though this decision is still subject to further review...
265          */
266         strip->flag = NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_AUTO_BLENDS;
267         
268         /* assign the action reference */
269         strip->act= act;
270         id_us_plus(&act->id);
271         
272         /* determine initial range 
273          *      - strip length cannot be 0... ever...
274          */
275         calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
276         
277         strip->start = strip->actstart;
278         strip->end = (IS_EQ(strip->actstart, strip->actend)) ?  (strip->actstart + 1.0f): (strip->actend);
279         
280         /* strip should be referenced as-is */
281         strip->scale= 1.0f;
282         strip->repeat = 1.0f;
283         
284         /* return the new strip */
285         return strip;
286 }
287
288 /* Add new NLA-strip to the top of the NLA stack - i.e. into the last track if space, or a new one otherwise */
289 NlaStrip *add_nlastrip_to_stack (AnimData *adt, bAction *act)
290 {
291         NlaStrip *strip, *ns;
292         NlaTrack *nlt;
293         short not_added = 1;
294         
295         /* sanity checks */
296         if ELEM(NULL, adt, act)
297                 return NULL;
298         
299         /* create a new NLA strip */
300         strip= add_nlastrip(act);
301         if (strip == NULL)
302                 return NULL;
303         
304         /* check if the last NLA-track (if it exists) has any space for this strip:
305          *      - if so, add this strip to that track
306          */
307         if ( (adt->nla_tracks.last == NULL) || 
308                  (BKE_nlatrack_has_space(adt->nla_tracks.last, strip->start, strip->end)==0) ) 
309         {
310                 /* no space, so add to a new track... */
311                 nlt= add_nlatrack(adt);
312         }
313         else 
314         {
315                 /* there's some space, so add to this track... */
316                 nlt= adt->nla_tracks.last;
317         }
318         
319         /* find the right place to add the strip to the nominated track */
320         for (ns= nlt->strips.first; ns; ns= ns->next) {
321                 /* if current strip occurs after the new strip, add it before */
322                 if (ns->start > strip->end) {
323                         BLI_insertlinkbefore(&nlt->strips, ns, strip);
324                         not_added= 0;
325                         break;
326                 }
327         }
328         if (not_added) {
329                 /* just add to the end of the list of the strips then... */
330                 BLI_addtail(&nlt->strips, strip);
331         }
332         
333         
334         /* returns the strip added */
335         return strip;
336 }
337
338 /* *************************************************** */
339 /* Basic Utilities */
340
341 /* NLA-Tracks ---------------------------------------- */
342
343 /* Find the active NLA-track for the given stack */
344 NlaTrack *BKE_nlatrack_find_active (ListBase *tracks)
345 {
346         NlaTrack *nlt;
347         
348         /* sanity check */
349         if ELEM(NULL, tracks, tracks->first)
350                 return NULL;
351                 
352         /* try to find the first active track */
353         for (nlt= tracks->first; nlt; nlt= nlt->next) {
354                 if (nlt->flag & NLATRACK_ACTIVE)
355                         return nlt;
356         }
357         
358         /* none found */
359         return NULL;
360 }
361
362 /* Toggle the 'solo' setting for the given NLA-track, making sure that it is the only one
363  * that has this status in its AnimData block.
364  */
365 void BKE_nlatrack_solo_toggle (AnimData *adt, NlaTrack *nlt)
366 {
367         NlaTrack *nt;
368         
369         /* sanity check */
370         if ELEM(NULL, adt, adt->nla_tracks.first)
371                 return;
372                 
373         /* firstly, make sure 'solo' flag for all tracks is disabled */
374         for (nt= adt->nla_tracks.first; nt; nt= nt->next) {
375                 if (nt != nlt)
376                         nt->flag &= ~NLATRACK_SOLO;
377         }
378                 
379         /* now, enable 'solo' for the given track if appropriate */
380         if (nlt) {
381                 /* toggle solo status */
382                 nlt->flag ^= NLATRACK_SOLO;
383                 
384                 /* set or clear solo-status on AnimData */
385                 if (nlt->flag & NLATRACK_SOLO)
386                         adt->flag |= ADT_NLA_SOLO_TRACK;
387                 else
388                         adt->flag &= ~ADT_NLA_SOLO_TRACK;
389         }
390         else
391                 adt->flag &= ~ADT_NLA_SOLO_TRACK;
392 }
393
394 /* Make the given NLA-track the active one for the given stack. If no track is provided, 
395  * this function can be used to simply deactivate all the NLA tracks in the given stack too.
396  */
397 void BKE_nlatrack_set_active (ListBase *tracks, NlaTrack *nlt_a)
398 {
399         NlaTrack *nlt;
400         
401         /* sanity check */
402         if ELEM(NULL, tracks, tracks->first)
403                 return;
404         
405         /* deactive all the rest */
406         for (nlt= tracks->first; nlt; nlt= nlt->next) 
407                 nlt->flag &= ~NLATRACK_ACTIVE;
408                 
409         /* set the given one as the active one */
410         if (nlt_a)
411                 nlt_a->flag |= NLATRACK_ACTIVE;
412 }
413
414 /* Check if there is any space in the last track to add the given strip */
415 short BKE_nlatrack_has_space (NlaTrack *nlt, float start, float end)
416 {
417         NlaStrip *strip;
418         
419         /* sanity checks */
420         if ((nlt == NULL) || IS_EQ(start, end))
421                 return 0;
422         if (start > end) {
423                 puts("BKE_nlatrack_has_space error... start and end arguments swapped");
424                 SWAP(float, start, end);
425         }
426         
427         /* loop over NLA strips checking for any overlaps with this area... */
428         for (strip= nlt->strips.first; strip; strip= strip->next) {
429                 /* if start frame of strip is past the target end-frame, that means that
430                  * we've gone past the window we need to check for, so things are fine
431                  */
432                 if (strip->start > end)
433                         return 1;
434                 
435                 /* if the end of the strip is greater than either of the boundaries, the range
436                  * must fall within the extents of the strip
437                  */
438                 if ((strip->end > start) || (strip->end > end))
439                         return 0;
440         }
441         
442         /* if we are still here, we haven't encountered any overlapping strips */
443         return 1;
444 }
445
446 /* Rearrange the strips in the track so that they are always in order 
447  * (usually only needed after a strip has been moved) 
448  */
449 void BKE_nlatrack_sort_strips (NlaTrack *nlt)
450 {
451         ListBase tmp = {NULL, NULL};
452         NlaStrip *strip, *sstrip;
453         
454         /* sanity checks */
455         if ELEM(NULL, nlt, nlt->strips.first)
456                 return;
457                 
458         /* we simply perform insertion sort on this list, since it is assumed that per track,
459          * there are only likely to be at most 5-10 strips
460          */
461         for (strip= nlt->strips.first; strip; strip= strip->next) {
462                 short not_added = 1;
463                 
464                 /* remove this strip from the list, and add it to the new list, searching from the end of 
465                  * the list, assuming that the lists are in order 
466                  */
467                 BLI_remlink(&nlt->strips, strip);
468                 
469                 for (sstrip= tmp.last; not_added && sstrip; sstrip= sstrip->prev) {
470                         /* check if add after */
471                         if (sstrip->end < strip->start) {
472                                 BLI_insertlinkafter(&tmp, sstrip, strip);
473                                 not_added= 0;
474                                 break;
475                         }
476                 }
477                 
478                 /* add before first? */
479                 if (not_added)
480                         BLI_addhead(&tmp, strip);
481         }
482         
483         /* reassign the start and end points of the strips */
484         nlt->strips.first= tmp.first;
485         nlt->strips.last= tmp.last;
486 }
487
488 /* NLA Strips -------------------------------------- */
489
490 /* Find the active NLA-strip within the given track */
491 NlaStrip *BKE_nlastrip_find_active (NlaTrack *nlt)
492 {
493         NlaStrip *strip;
494         
495         /* sanity check */
496         if ELEM(NULL, nlt, nlt->strips.first)
497                 return NULL;
498                 
499         /* try to find the first active strip */
500         for (strip= nlt->strips.first; strip; strip= strip->next) {
501                 if (strip->flag & NLASTRIP_FLAG_ACTIVE)
502                         return strip;
503         }
504         
505         /* none found */
506         return NULL;
507 }
508
509 /* Does the given NLA-strip fall within the given bounds (times)? */
510 short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max)
511 {
512         const float stripLen= (strip) ? strip->end - strip->start : 0.0f;
513         const float boundsLen= (float)fabs(max - min);
514         
515         /* sanity checks */
516         if ((strip == NULL) || IS_EQ(stripLen, 0.0f) || IS_EQ(boundsLen, 0.0f))
517                 return 0;
518         
519         /* only ok if at least part of the strip is within the bounding window
520          *      - first 2 cases cover when the strip length is less than the bounding area
521          *      - second 2 cases cover when the strip length is greater than the bounding area
522          */
523         if ( (stripLen < boundsLen) && 
524                  !(IN_RANGE(strip->start, min, max) ||
525                    IN_RANGE(strip->end, min, max)) )
526         {
527                 return 0;
528         }
529         if ( (stripLen > boundsLen) && 
530                  !(IN_RANGE(min, strip->start, strip->end) ||
531                    IN_RANGE(max, strip->start, strip->end)) )
532         {
533                 return 0;
534         }
535         
536         /* should be ok! */
537         return 1;
538 }
539
540 /* Is the given NLA-strip the first one to occur for the given AnimData block */
541 // TODO: make this an api method if necesary, but need to add prefix first
542 short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
543 {
544         NlaTrack *nlt;
545         NlaStrip *ns;
546         
547         /* sanity checks */
548         if ELEM(NULL, adt, strip)
549                 return 0;
550                 
551         /* check if strip has any strips before it */
552         if (strip->prev)
553                 return 0;
554                 
555         /* check other tracks to see if they have a strip that's earlier */
556         // TODO: or should we check that the strip's track is also the first?
557         for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
558                 /* only check the first strip, assuming that they're all in order */
559                 ns= nlt->strips.first;
560                 if (ns) {
561                         if (ns->start < strip->start)
562                                 return 0;
563                 }
564         }       
565         
566         /* should be first now */
567         return 1;
568 }
569
570 /* Tools ------------------------------------------- */
571
572 /* For the given AnimData block, add the active action to the NLA
573  * stack (i.e. 'push-down' action). The UI should only allow this 
574  * for normal editing only (i.e. not in editmode for some strip's action),
575  * so no checks for this are performed.
576  */
577 // TODO: maybe we should have checks for this too...
578 void BKE_nla_action_pushdown (AnimData *adt)
579 {
580         NlaStrip *strip;
581         
582         /* sanity checks */
583         // TODO: need to report the error for this
584         if ELEM(NULL, adt, adt->action) 
585                 return;
586                 
587         /* if the action is empty, we also shouldn't try to add to stack, 
588          * as that will cause us grief down the track
589          */
590         // TODO: what about modifiers?
591         if (action_has_motion(adt->action) == 0) {
592                 printf("BKE_nla_action_pushdown(): action has no data \n");
593                 return;
594         }
595         
596         /* add a new NLA strip to the track, which references the active action */
597         strip= add_nlastrip_to_stack(adt, adt->action);
598         
599         /* do other necessary work on strip */  
600         if (strip) {
601                 /* clear reference to action now that we've pushed it onto the stack */
602                 adt->action->id.us--;
603                 adt->action= NULL;
604                 
605                 /* if the strip is the first one in the track it lives in, check if there
606                  * are strips in any other tracks that may be before this, and set the extend
607                  * mode accordingly
608                  */
609                 if (nlastrip_is_first(adt, strip) == 0) {
610                         /* not first, so extend mode can only be NLASTRIP_EXTEND_HOLD_FORWARD not NLASTRIP_EXTEND_HOLD,
611                          * so that it doesn't override strips in previous tracks
612                          */
613                         strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD;
614                 }
615         }
616 }
617
618
619 /* Find the active strip + track combo, and set them up as the tweaking track,
620  * and return if successful or not.
621  */
622 short BKE_nla_tweakmode_enter (AnimData *adt)
623 {
624         NlaTrack *nlt, *activeTrack=NULL;
625         NlaStrip *strip, *activeStrip=NULL;
626         
627         /* verify that data is valid */
628         if ELEM(NULL, adt, adt->nla_tracks.first)
629                 return 0;
630                 
631         /* if block is already in tweakmode, just leave, but we should report 
632          * that this block is in tweakmode (as our returncode)
633          */
634         // FIXME: hopefully the flag is correct!
635         if (adt->flag & ADT_NLA_EDIT_ON)
636                 return 1;
637                 
638         /* go over the tracks, finding the active one, and its active strip
639          *      - if we cannot find both, then there's nothing to do
640          */
641         for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
642                 /* check if active */
643                 if (nlt->flag & NLATRACK_ACTIVE) {
644                         /* store reference to this active track */
645                         activeTrack= nlt;
646                         
647                         /* now try to find active strip */
648                         activeStrip= BKE_nlastrip_find_active(nlt);
649                         break;
650                 }       
651         }
652         if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) {
653                 printf("NLA tweakmode enter - neither active requirement found \n");
654                 return 0;
655         }
656                 
657         /* go over all the tracks up to the active one, tagging each strip that uses the same 
658          * action as the active strip, but leaving everything else alone
659          */
660         for (nlt= activeTrack->prev; nlt; nlt= nlt->prev) {
661                 for (strip= nlt->strips.first; strip; strip= strip->next) {
662                         if (strip->act == activeStrip->act)
663                                 strip->flag |= NLASTRIP_FLAG_TWEAKUSER;
664                         else
665                                 strip->flag &= ~NLASTRIP_FLAG_TWEAKUSER; // XXX probably don't need to clear this...
666                 }
667         }
668         
669         
670         /* go over all the tracks after AND INCLUDING the active one, tagging them as being disabled 
671          *      - the active track needs to also be tagged, otherwise, it'll overlap with the tweaks going on
672          */
673         for (nlt= activeTrack; nlt; nlt= nlt->next)
674                 nlt->flag |= NLATRACK_DISABLED;
675         
676         /* handle AnimData level changes:
677          *      - 'real' active action to temp storage (no need to change user-counts)
678          *      - action of active strip set to be the 'active action'
679          *      - editing-flag for this AnimData block should also get turned on (for more efficient restoring)
680          */
681         adt->tmpact= adt->action;
682         adt->action= activeStrip->act;
683         adt->flag |= ADT_NLA_EDIT_ON;
684         
685         /* done! */
686         return 1;
687 }
688
689 /* Exit tweakmode for this AnimData block */
690 void BKE_nla_tweakmode_exit (AnimData *adt)
691 {
692         NlaTrack *nlt;
693         
694         /* verify that data is valid */
695         if ELEM(NULL, adt, adt->nla_tracks.first)
696                 return;
697                 
698         /* hopefully the flag is correct - skip if not on */
699         if ((adt->flag & ADT_NLA_EDIT_ON) == 0)
700                 return;
701                 
702         // TODO: need to sync the user-strip with the new state of the action!
703                 
704         /* for all NLA-tracks, clear the 'disabled' flag */
705         for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next)
706                 nlt->flag &= ~NLATRACK_DISABLED;
707         
708         /* handle AnimData level changes:
709          *      - 'real' active action is restored from storage
710          *      - storage pointer gets cleared (to avoid having bad notes hanging around)
711          *      - editing-flag for this AnimData block should also get turned off
712          */
713         adt->action= adt->tmpact;
714         adt->tmpact= NULL;
715         adt->flag &= ~ADT_NLA_EDIT_ON;
716 }
717
718 /* *************************************************** */