Bugfix #3720
[blender.git] / source / blender / blenkernel / intern / action.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <string.h>
36 #include <math.h>
37 #include <stdlib.h>     /* for NULL */
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_action_types.h"
42 #include "DNA_armature_types.h"
43 #include "DNA_constraint_types.h"
44 #include "DNA_curve_types.h"
45 #include "DNA_ipo_types.h"
46 #include "DNA_key_types.h"
47 #include "DNA_nla_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_scene_types.h"
50
51 #include "BKE_action.h"
52 #include "BKE_anim.h"
53 #include "BKE_armature.h"
54 #include "BKE_blender.h"
55 #include "BKE_constraint.h"
56 #include "BKE_displist.h"
57 #include "BKE_global.h"
58 #include "BKE_ipo.h"
59 #include "BKE_key.h"
60 #include "BKE_library.h"
61 #include "BKE_main.h"
62 #include "BKE_object.h"
63 #include "BKE_utildefines.h"
64
65 #include "BLI_arithb.h"
66 #include "BLI_blenlib.h"
67
68 #include "nla.h"
69
70 /* *********************** NOTE ON POSE AND ACTION **********************
71
72   - Pose is the local (object level) component of armature. The current
73     object pose is saved in files, and (will be) is presorted for dependency
74   - Actions have fewer (or other) channels, and write data to a Pose
75   - Currently ob->pose data is controlled in where_is_pose only. The (recalc)
76     event system takes care of calling that
77   - The NLA system (here too) uses Poses as interpolation format for Actions
78   - Therefore we assume poses to be static, and duplicates of poses have channels in
79     same order, for quick interpolation reasons
80
81   ****************************** (ton) ************************************ */
82
83 /* ***************** Library data level operations on action ************** */
84
85 static void make_local_action_channels(bAction *act)
86 {
87         bActionChannel *chan;
88         bConstraintChannel *conchan;
89         
90         for (chan=act->chanbase.first; chan; chan=chan->next) {
91                 if(chan->ipo) {
92                         if(chan->ipo->id.us==1) {
93                                 chan->ipo->id.lib= NULL;
94                                 chan->ipo->id.flag= LIB_LOCAL;
95                                 new_id(0, (ID *)chan->ipo, 0);
96                         }
97                         else {
98                                 chan->ipo= copy_ipo(chan->ipo);
99                         }
100                 }
101                 for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
102                         if(conchan->ipo) {
103                                 if(conchan->ipo->id.us==1) {
104                                         conchan->ipo->id.lib= NULL;
105                                         conchan->ipo->id.flag= LIB_LOCAL;
106                                         new_id(0, (ID *)conchan->ipo, 0);
107                                 }
108                                 else {
109                                         conchan->ipo= copy_ipo(conchan->ipo);
110                                 }
111                         }
112                 }
113         }
114                                         
115 }
116
117 void make_local_action(bAction *act)
118 {
119         Object *ob;
120         bAction *actn;
121         int local=0, lib=0;
122         
123         if(act->id.lib==0) return;
124         if(act->id.us==1) {
125                 act->id.lib= 0;
126                 act->id.flag= LIB_LOCAL;
127                 make_local_action_channels(act);
128                 new_id(0, (ID *)act, 0);
129                 return;
130         }
131         
132         ob= G.main->object.first;
133         while(ob) {
134                 if(ob->action==act) {
135                         if(ob->id.lib) lib= 1;
136                         else local= 1;
137                 }
138                 ob= ob->id.next;
139         }
140         
141         if(local && lib==0) {
142                 act->id.lib= 0;
143                 act->id.flag= LIB_LOCAL;
144                 make_local_action_channels(act);
145                 new_id(0, (ID *)act, 0);
146         }
147         else if(local && lib) {
148                 actn= copy_action(act);
149                 actn->id.us= 0;
150                 
151                 ob= G.main->object.first;
152                 while(ob) {
153                         if(ob->action==act) {
154                                 
155                                 if(ob->id.lib==0) {
156                                         ob->action = actn;
157                                         actn->id.us++;
158                                         act->id.us--;
159                                 }
160                         }
161                         ob= ob->id.next;
162                 }
163         }
164 }
165
166
167 void free_action(bAction *act)
168 {
169         bActionChannel *chan;
170         
171         /* Free channels */
172         for (chan=act->chanbase.first; chan; chan=chan->next){
173                 if (chan->ipo)
174                         chan->ipo->id.us--;
175                 free_constraint_channels(&chan->constraintChannels);
176         }
177         
178         if (act->chanbase.first)
179                 BLI_freelistN (&act->chanbase);
180 }
181
182 bAction* copy_action(bAction *src)
183 {
184         bAction *dst = NULL;
185         bActionChannel *dchan, *schan;
186         
187         if(!src) return NULL;
188         
189         dst= copy_libblock(src);
190         duplicatelist(&(dst->chanbase), &(src->chanbase));
191         
192         for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){
193                 dchan->ipo = copy_ipo(dchan->ipo);
194                 copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels);
195         }
196         dst->id.flag |= LIB_FAKEUSER;
197         dst->id.us++;
198         return dst;
199 }
200
201
202
203 /* ************************ Pose channels *************** */
204
205 /* usually used within a loop, so we got a N^2 slowdown */
206 bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
207 {
208         bPoseChannel *chan;
209
210         if(pose==NULL) return NULL;
211         
212         for (chan=pose->chanbase.first; chan; chan=chan->next) {
213                 if(chan->name[0] == name[0])
214                         if (!strcmp (chan->name, name))
215                                 return chan;
216         }
217
218         return NULL;
219 }
220
221 /* Use with care, not on Armature poses but for temporal ones */
222 /* (currently used for action constraints and in rebuild_pose) */
223 bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
224 {
225         bPoseChannel *chan;
226         
227         if (!pose){
228                 return NULL;
229         }
230         
231         /*      See if this channel exists */
232         for (chan=pose->chanbase.first; chan; chan=chan->next){
233                 if (!strcmp (name, chan->name))
234                         return chan;
235         }
236         
237         /* If not, create it and add it */
238         chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
239         
240         strncpy (chan->name, name, 31);
241         /* init vars to prevent mat errors */
242         chan->quat[0] = 1.0F;
243         chan->size[0] = chan->size[1] = chan->size[2] = 1.0F;
244         
245         chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f;
246         chan->limitmax[0]= chan->limitmax[1]= chan->limitmax[2]= 180.0f;
247         chan->stiffness[0]= chan->stiffness[1]= chan->stiffness[2]= 0.0f;
248         
249         BLI_addtail (&pose->chanbase, chan);
250         
251         return chan;
252 }
253
254
255 /* dst should be freed already, makes entire duplicate */
256 void copy_pose(bPose **dst, bPose *src, int copycon)
257 {
258         bPose *outPose;
259         bPoseChannel    *pchan;
260         ListBase listb;
261         
262         if (!src){
263                 *dst=NULL;
264                 return;
265         }
266         
267         outPose= MEM_callocN(sizeof(bPose), "pose");
268         
269         duplicatelist (&outPose->chanbase, &src->chanbase);
270         
271         if (copycon) {
272                 for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
273                         copy_constraints(&listb, &pchan->constraints);  // copy_constraints NULLs listb
274                         pchan->constraints= listb;
275                         pchan->path= NULL;
276                 }
277         }
278         
279         *dst=outPose;
280 }
281
282 void free_pose_channels(bPose *pose) 
283 {
284         bPoseChannel *pchan;
285         
286         if (pose->chanbase.first){
287                 for (pchan = pose->chanbase.first; pchan; pchan=pchan->next){
288                         if(pchan->path)
289                                 MEM_freeN(pchan->path);
290                         free_constraints(&pchan->constraints);
291                 }
292                 BLI_freelistN (&pose->chanbase);
293         }
294 }
295
296 static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
297 {
298         bConstraint *pcon, *con;
299         
300         VECCOPY(pchan->loc, chan->loc);
301         VECCOPY(pchan->size, chan->size);
302         QUATCOPY(pchan->quat, chan->quat);
303         pchan->flag= chan->flag;
304         
305         con= chan->constraints.first;
306         for(pcon= pchan->constraints.first; pcon; pcon= pcon->next)
307                 pcon->enforce= con->enforce;
308 }
309
310 /* checks for IK constraint, can do more constraints flags later */
311 /* pose should be entirely OK */
312 void update_pose_constraint_flags(bPose *pose)
313 {
314         bPoseChannel *pchan, *parchan;
315         bConstraint *con;
316         
317         /* clear */
318         for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
319                 pchan->constflag= 0;
320         }
321         /* detect */
322         for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
323                 for(con= pchan->constraints.first; con; con= con->next) {
324                         if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
325                                 bKinematicConstraint *data = (bKinematicConstraint*)con->data;
326                                 
327                                 pchan->constflag |= PCHAN_HAS_IK;
328                                 
329                                 if(data->tar==NULL || (data->tar->type==OB_ARMATURE && data->subtarget[0]==0))
330                                         pchan->constflag |= PCHAN_HAS_TARGET;
331                                 
332                                 /* negative rootbone = recalc rootbone index. used in do_versions */
333                                 if(data->rootbone<0) {
334                                         data->rootbone= 0;
335                                         
336                                         if(data->flag & CONSTRAINT_IK_TIP) parchan= pchan;
337                                         else parchan= pchan->parent;
338                                         
339                                         while(parchan) {
340                                                 data->rootbone++;
341                                                 if((parchan->bone->flag & BONE_CONNECTED)==0)
342                                                         break;
343                                                 parchan= parchan->parent;
344                                         }
345                                 }
346                         }
347                         else pchan->constflag |= PCHAN_HAS_CONST;
348                 }
349         }
350 }
351
352
353 /* ************************ END Pose channels *************** */
354
355 /* ************************ Action channels *************** */
356
357
358 bActionChannel *get_action_channel(bAction *act, const char *name)
359 {
360         bActionChannel *chan;
361         
362         if (!act)
363                 return NULL;
364         
365         for (chan = act->chanbase.first; chan; chan=chan->next){
366                 if (!strcmp (chan->name, name))
367                         return chan;
368         }
369         
370         return NULL;
371 }
372
373 /* returns existing channel, or adds new one. In latter case it doesnt activate it, context is required for that*/
374 bActionChannel *verify_action_channel(bAction *act, const char *name)
375 {
376         bActionChannel *chan;
377         
378         chan= get_action_channel(act, name);
379         if(chan==NULL) {
380                 if (!chan) {
381                         chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
382                         strncpy (chan->name, name, 31);
383                         BLI_addtail (&act->chanbase, chan);
384                 }
385         }
386         return chan;
387 }
388
389 /* ************************ Blending with NLA *************** */
390
391 static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mode)
392 {
393         float dstweight;
394         
395         switch (mode){
396                 case POSE_BLEND:
397                         dstweight = 1.0F - srcweight;
398                         break;
399                 case POSE_ADD:
400                         dstweight = 1.0F;
401                         break;
402                 default :
403                         dstweight = 1.0F;
404         }
405         
406         VecLerpf(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight);
407 }
408
409 /* Only allowed for Poses with identical channels */
410 void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
411 {
412         bPoseChannel *dchan;
413         const bPoseChannel *schan;
414         bConstraint *dcon, *scon;
415         float   dquat[4], squat[4];
416         float dstweight;
417         int i;
418         
419         switch (mode){
420         case POSE_BLEND:
421                 dstweight = 1.0F - srcweight;
422                 break;
423         case POSE_ADD:
424                 dstweight = 1.0F;
425                 break;
426         default :
427                 dstweight = 1.0F;
428         }
429         
430         schan= src->chanbase.first;
431         for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
432                 if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
433                         /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
434                         
435                         /* Do the transformation blend */
436                         if (schan->flag & POSE_ROT) {
437                                 QUATCOPY(dquat, dchan->quat);
438                                 QUATCOPY(squat, schan->quat);
439                                 if(mode==POSE_BLEND)
440                                         QuatInterpol(dchan->quat, dquat, squat, srcweight);
441                                 else
442                                         QuatAdd(dchan->quat, dquat, squat, srcweight);
443                                 
444                                 NormalQuat (dchan->quat);
445                         }
446
447                         for (i=0; i<3; i++){
448                                 if (schan->flag & POSE_LOC)
449                                         dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
450                                 if (schan->flag & POSE_SIZE)
451                                         dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
452                         }
453                         dchan->flag |= schan->flag;
454                 }
455                 for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
456                         /* no 'add' option for constraint blending */
457                         dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
458                 }
459         }
460 }
461
462
463 void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
464 {
465         const bActionChannel *chan;
466         const bConstraintChannel *conchan;
467         const IpoCurve  *icu;
468         float min=999999999.0f, max=-999999999.0;
469         int     foundvert=0;
470
471         if(act) {
472                 for (chan=act->chanbase.first; chan; chan=chan->next) {
473                         if(incl_hidden || (chan->flag & ACHAN_HIDDEN)==0) {
474                                 if(chan->ipo) {
475                                         for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
476                                                 if(icu->totvert) {
477                                                         min= MIN2 (min, icu->bezt[0].vec[1][0]);
478                                                         max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]);
479                                                         foundvert=1;
480                                                 }
481                                         }
482                                 }
483                                 for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
484                                         if(conchan->ipo) {
485                                                 for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
486                                                         if(icu->totvert) {
487                                                                 min= MIN2 (min, icu->bezt[0].vec[1][0]);
488                                                                 max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]);
489                                                                 foundvert=1;
490                                                         }
491                                                 }
492                                         }
493                                 }
494                         }
495                 }
496         }       
497         if (foundvert) {
498                 if(min==max) max+= 1.0f;
499                 *start= min;
500                 *end= max;
501         }
502         else {
503                 *start= 0.0f;
504                 *end= 1.0f;
505         }
506 }
507
508 /* Copy the data from the action-pose (src) into the pose */
509 /* both args are assumed to be valid */
510 /* exported to game engine */
511 void extract_pose_from_pose(bPose *pose, const bPose *src)
512 {
513         const bPoseChannel *schan;
514         bPoseChannel *pchan= pose->chanbase.first;
515
516         for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) {
517                 copy_pose_channel_data(pchan, schan);
518         }
519 }
520
521 /* Pose should exist, can have any number of channels too (used for constraint) */
522 void extract_pose_from_action(bPose *pose, bAction *act, float ctime) 
523 {
524         bActionChannel *achan;
525         bPoseChannel    *pchan;
526         Ipo                             *ipo;
527
528         if (!act)
529                 return;
530         if (!pose)
531                 return;
532         
533         /* Copy the data from the action into the pose */
534         for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
535                 achan= get_action_channel(act, pchan->name);
536                 pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
537                 if(achan) {
538                         ipo = achan->ipo;
539                         if (ipo) {
540                                 /* Evaluates and sets the internal ipo value */
541                                 calc_ipo(ipo, ctime);
542                                 /* This call also sets the pchan flags */
543                                 execute_action_ipo(achan, pchan);
544                         }
545                         do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
546                 }
547         }
548 }
549
550 /* for do_all_pose_actions, clears the pose */
551 static void rest_pose(bPose *pose)
552 {
553         bPoseChannel *pchan;
554         int i;
555         
556         if (!pose)
557                 return;
558         
559         pose->stride_offset[0]= 0.0f;
560         pose->stride_offset[1]= 0.0f;
561         pose->stride_offset[2]= 0.0f;
562         
563         for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
564                 for (i=0; i<3; i++){
565                         pchan->loc[i]=0.0;
566                         pchan->quat[i+1]=0.0;
567                         pchan->size[i]=1.0;
568                 }
569                 pchan->quat[0]=1.0;
570                 
571                 pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
572         }
573 }
574
575 /* ********** NLA with non-poses works with ipo channels ********** */
576
577 typedef struct NlaIpoChannel {
578         struct NlaIpoChannel *next, *prev;
579         float val;
580         void *poin;
581         int type;
582 } NlaIpoChannel;
583
584 static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime)
585 {
586         bActionChannel *achan= get_action_channel(act, name);
587         IpoCurve *icu;
588         NlaIpoChannel *nic;
589         
590         if(achan==NULL) return;
591         
592         if(achan->ipo) {
593                 calc_ipo(achan->ipo, ctime);
594                 
595                 for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
596                         
597                         nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel");
598                         BLI_addtail(lb, nic);
599                         nic->val= icu->curval;
600                         nic->poin= get_ipo_poin(id, icu, &nic->type);
601                 }
602         }
603         
604         /* constraint channels only for objects */
605         if(GS(id->name)==ID_OB) {
606                 Object *ob= (Object *)id;
607                 bConstraint *con;
608                 bConstraintChannel *conchan;
609                 
610                 for (con=ob->constraints.first; con; con=con->next) {
611                         conchan = get_constraint_channel(&achan->constraintChannels, con->name);
612                         
613                         if(conchan && conchan->ipo) {
614                                 calc_ipo(conchan->ipo, ctime);
615
616                                 icu= conchan->ipo->curve.first; // only one ipo now
617                                 if(icu) {
618                                         nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel constr");
619                                         BLI_addtail(lb, nic);
620                                         nic->val= icu->curval;
621                                         nic->poin= &con->enforce;
622                                         nic->type= IPO_FLOAT;
623                                 }
624                         }
625                 }
626         }
627 }
628
629 static NlaIpoChannel *find_nla_ipochannel(ListBase *lb, void *poin)
630 {
631         NlaIpoChannel *nic;
632         
633         if(poin) {
634                 for(nic= lb->first; nic; nic= nic->next) {
635                         if(nic->poin==poin)
636                                 return nic;
637                 }
638         }
639         return NULL;
640 }
641
642
643 static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int mode)
644 {
645         NlaIpoChannel *snic, *dnic, *next;
646         float dstweight;
647         
648         switch (mode){
649                 case POSE_BLEND:
650                         dstweight = 1.0F - srcweight;
651                         break;
652                 case POSE_ADD:
653                         dstweight = 1.0F;
654                         break;
655                 default :
656                         dstweight = 1.0F;
657         }
658         
659         for(snic= src->first; snic; snic= next) {
660                 next= snic->next;
661                 
662                 dnic= find_nla_ipochannel(dst, snic->poin);
663                 if(dnic==NULL) {
664                         /* remove from src list, and insert in dest */
665                         BLI_remlink(src, snic);
666                         BLI_addtail(dst, snic);
667                 }
668                 else {
669                         /* we do the blend */
670                         dnic->val= dstweight*dnic->val + srcweight*snic->val;
671                 }
672         }
673 }
674
675 static void execute_ipochannels(ListBase *lb)
676 {
677         NlaIpoChannel *nic;
678         
679         for(nic= lb->first; nic; nic= nic->next) {
680                 if(nic->poin) {
681                         write_ipo_poin(nic->poin, nic->type, nic->val);
682                 }
683         }
684 }
685
686
687 /* ************** time ****************** */
688
689 static bActionStrip *get_active_strip(Object *ob)
690 {
691         bActionStrip *strip;
692         
693         if(ob->action==NULL)
694                 return NULL;
695         
696         for (strip=ob->nlastrips.first; strip; strip=strip->next)
697                 if(strip->flag & ACTSTRIP_ACTIVE)
698                         break;
699         
700         if(strip && strip->act==ob->action)
701                 return strip;
702         return NULL;
703 }
704
705 /* non clipped mapping of strip */
706 static float get_actionstrip_frame(bActionStrip *strip, float cframe, int invert)
707 {
708         float length, actlength, repeat;
709         
710         if (strip->flag & ACTSTRIP_USESTRIDE)
711                 repeat= 1.0f;
712         else
713                 repeat= strip->repeat;
714         
715         length = strip->end-strip->start;
716         if(length==0.0f)
717                 length= 1.0f;
718         actlength = strip->actend-strip->actstart;
719
720         
721         
722         if(invert)
723                 return length*(cframe - strip->actstart)/(repeat*actlength) + strip->start;
724         else
725                 return repeat*actlength*(cframe - strip->start)/length + strip->actstart;
726 }
727
728 /* if the conditions match, it converts current time to strip time */
729 float get_action_frame(Object *ob, float cframe)
730 {
731         bActionStrip *strip= get_active_strip(ob);
732         
733         if(strip)
734                 return get_actionstrip_frame(strip, cframe, 0);
735         return cframe;
736 }
737
738 /* inverted, strip time to current time */
739 float get_action_frame_inv(Object *ob, float cframe)
740 {
741         bActionStrip *strip= get_active_strip(ob);
742         
743         if(strip)
744                 return get_actionstrip_frame(strip, cframe, 1);
745         return cframe;
746 }
747
748
749
750 /* this now only used for repeating cycles, to enable fields and blur. */
751 /* the whole time control in blender needs serious thinking... */
752 static float nla_time(float cfra, float unit)
753 {
754         extern float bluroffs;  // bad construct, borrowed from object.c for now
755         
756         /* 2nd field */
757 //      if(R.flag & R_SEC_FIELD) {
758 //              if(R.r.mode & R_FIELDSTILL); else cfra+= 0.5f*unit;
759 //      }
760         
761         /* motion blur */
762         cfra+= unit*bluroffs;
763                 
764         /* global time */
765         cfra*= G.scene->r.framelen;     
766
767
768         /* decide later... */
769 //      if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra);
770
771         return cfra;
772 }
773
774 static float stridechannel_frame(Object *ob, bActionStrip *strip, Path *path, float pathdist, float *stride_offset)
775 {
776         bAction *act= strip->act;
777         char *name= strip->stridechannel;
778         bActionChannel *achan= get_action_channel(act, name);
779         int stride_axis= strip->stride_axis;
780
781         if(achan && achan->ipo) {
782                 IpoCurve *icu= NULL;
783                 float minx=0.0f, maxx=0.0f, miny=0.0f, maxy=0.0f;
784                 int foundvert= 0;
785                 
786                 if(stride_axis==0) stride_axis= AC_LOC_X;
787                 else if(stride_axis==1) stride_axis= AC_LOC_Y;
788                 else stride_axis= AC_LOC_Z;
789                 
790                 /* calculate the min/max */
791                 for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
792                         if(icu->adrcode==stride_axis) {
793                                 if(icu->totvert>1) {
794                                         foundvert= 1;
795                                         minx= icu->bezt[0].vec[1][0];
796                                         maxx= icu->bezt[icu->totvert-1].vec[1][0];
797                                         
798                                         miny= icu->bezt[0].vec[1][1];
799                                         maxy= icu->bezt[icu->totvert-1].vec[1][1];
800                                 }
801                                 break;
802                         }
803                 }
804                 
805                 if(foundvert && miny!=maxy) {
806                         float stridelen= fabs(maxy-miny), striptime;
807                         float actiondist, pdist, pdistNewNormalized, offs;
808                         float vec1[4], vec2[4], dir[3];
809                         
810                         /* internal cycling, actoffs is in frames */
811                         offs= stridelen*strip->actoffs/(maxx-minx);
812                         
813                         /* amount path moves object */
814                         pdist = (float)fmod (pathdist+offs, stridelen);
815                         striptime= pdist/stridelen;
816                         
817                         /* amount stride bone moves */
818                         actiondist= eval_icu(icu, minx + striptime*(maxx-minx)) - miny;
819                         
820                         pdist = fabs(actiondist) - pdist;
821                         pdistNewNormalized = (pathdist+pdist)/path->totdist;
822                         
823                         /* now we need to go pdist further (or less) on cu path */
824                         where_on_path(ob, (pathdist)/path->totdist, vec1, dir); /* vec needs size 4 */
825                         if (pdistNewNormalized <= 1) {
826                                 // search for correction in positive path-direction
827                                 where_on_path(ob, pdistNewNormalized, vec2, dir);       /* vec needs size 4 */
828                                 VecSubf(stride_offset, vec2, vec1);
829                         }
830                         else {
831                                 // we reached the end of the path, search backwards instead
832                                 where_on_path(ob, (pathdist-pdist)/path->totdist, vec2, dir);   /* vec needs size 4 */
833                                 VecSubf(stride_offset, vec1, vec2);
834                         }
835                         Mat4Mul3Vecfl(ob->obmat, stride_offset);
836                         return striptime;
837                 }
838         }
839         return 0.0f;
840 }
841
842 /* simple case for now; only the curve path with constraint value > 0.5 */
843 /* blending we might do later... */
844 static Object *get_parent_path(Object *ob)
845 {
846         bConstraint *con;
847         
848         if(ob->parent && ob->parent->type==OB_CURVE)
849                 return ob->parent;
850         
851         for (con = ob->constraints.first; con; con=con->next) {
852                 if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) {
853                         if(con->enforce>0.5f) {
854                                 bFollowPathConstraint *data= con->data;
855                                 return data->tar;
856                         }
857                 }
858         }
859         return NULL;
860 }
861
862 /* ************** do the action ************ */
863
864 static void do_nla(Object *ob, int blocktype)
865 {
866         bPose *tpose= NULL;
867         Key *key= NULL;
868         ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL};
869         bActionStrip *strip, *striplast=NULL, *stripfirst=NULL;
870         float striptime, frametime, length, actlength;
871         float blendfac, stripframe;
872         float scene_cfra= G.scene->r.cfra;
873         int     doit, dostride;
874         
875         if(blocktype==ID_AR) {
876                 copy_pose(&tpose, ob->pose, 1);
877                 rest_pose(ob->pose);            // potentially destroying current not-keyed pose
878         }
879         else {
880                 key= ob_get_key(ob);
881         }
882         
883         /* check on extend to left or right, when no strip is hit by 'cfra' */
884         for (strip=ob->nlastrips.first; strip; strip=strip->next) {
885                 /* escape loop on a hit */
886                 if( scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f)      /* note 0.1 comes back below */
887                         break;
888                 if(scene_cfra < strip->start) {
889                         if(stripfirst==NULL)
890                                 stripfirst= strip;
891                         else if(stripfirst->start > strip->start)
892                                 stripfirst= strip;
893                 }
894                 else if(scene_cfra > strip->end) {
895                         if(striplast==NULL)
896                                 striplast= strip;
897                         else if(striplast->end < strip->end)
898                                 striplast= strip;
899                 }
900         }
901         if(strip==NULL) {       /* extend */
902                 if(stripfirst)
903                         scene_cfra= stripfirst->start;
904                 else if(striplast)
905                         scene_cfra= striplast->end;
906         }
907         
908         /* and now go over all strips */
909         for (strip=ob->nlastrips.first; strip; strip=strip->next){
910                 doit=dostride= 0;
911                 
912                 if (strip->act){        /* so theres an action */
913                         
914                         /* Determine if the current frame is within the strip's range */
915                         length = strip->end-strip->start;
916                         actlength = strip->actend-strip->actstart;
917                         striptime = (scene_cfra-(strip->start)) / length;
918                         stripframe = (scene_cfra-(strip->start)) ;
919                         
920                         if (striptime>=0.0){
921                                 
922                                 if(blocktype==ID_AR) 
923                                         rest_pose(tpose);
924                                 
925                                 /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
926                                 if (striptime < 1.0f + 0.1f/length) {
927                                         
928                                         /* Handle path */
929                                         if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype==ID_AR) && (ob->ipoflag & OB_DISABLE_PATH)==0){
930                                                 Object *parent= get_parent_path(ob);
931                                                 
932                                                 if (parent) {
933                                                         Curve *cu = parent->data;
934                                                         float ctime, pdist;
935                                                         
936                                                         if (cu->flag & CU_PATH){
937                                                                 /* Ensure we have a valid path */
938                                                                 if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(parent, 0);
939                                                                 if(cu->path) {
940                                                                         
941                                                                         /* Find the position on the path */
942                                                                         ctime= bsystem_time(ob, parent, scene_cfra, 0.0);
943                                                                         
944                                                                         if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
945                                                                                 /* correct for actions not starting on zero */
946                                                                                 ctime= (ctime - strip->actstart)/cu->pathlen;
947                                                                                 CLAMP(ctime, 0.0, 1.0);
948                                                                         }
949                                                                         pdist = ctime*cu->path->totdist;
950                                                                         
951                                                                         if(tpose && strip->stridechannel[0]) {
952                                                                                 striptime= stridechannel_frame(parent, strip, cu->path, pdist, tpose->stride_offset);
953                                                                         }                                                                       
954                                                                         else {
955                                                                                 if (strip->stridelen) {
956                                                                                         striptime = pdist / strip->stridelen;
957                                                                                         striptime = (float)fmod (striptime+strip->actoffs, 1.0);
958                                                                                 }
959                                                                                 else
960                                                                                         striptime = 0;
961                                                                         }
962                                                                         
963                                                                         frametime = (striptime * actlength) + strip->actstart;
964                                                                         frametime= bsystem_time(ob, 0, frametime, 0.0);
965                                                                         
966                                                                         if(blocktype==ID_AR) {
967                                                                                 extract_pose_from_action (tpose, strip->act, frametime);
968                                                                         }
969                                                                         else if(blocktype==ID_OB) {
970                                                                                 extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
971                                                                                 if(key)
972                                                                                         extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
973                                                                         }
974                                                                         doit=dostride= 1;
975                                                                 }
976                                                         }
977                                                 }
978                                         }
979                                         /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
980                                         else  {
981                                                 
982                                                 /* Mod to repeat */
983                                                 if(strip->repeat!=1.0f) {
984                                                         striptime*= strip->repeat;
985                                                         striptime = (float)fmod (striptime, 1.0f + 0.1f/length);
986                                                 }
987
988                                                 frametime = (striptime * actlength) + strip->actstart;
989                                                 frametime= nla_time(frametime, (float)strip->repeat);
990                                                         
991                                                 if(blocktype==ID_AR)
992                                                         extract_pose_from_action (tpose, strip->act, frametime);
993                                                 else if(blocktype==ID_OB) {
994                                                         extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
995                                                         if(key)
996                                                                 extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
997                                                 }                                               
998                                                 doit=1;
999                                         }
1000                                 }
1001                                 /* Handle extend */
1002                                 else{
1003                                         if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
1004                                                 /* we want the strip to hold on the exact fraction of the repeat value */
1005                                                 
1006                                                 frametime = actlength * (strip->repeat-(int)strip->repeat);
1007                                                 if(frametime<=0.000001f) frametime= actlength;  /* rounding errors... */
1008                                                 frametime= bsystem_time(ob, 0, frametime+strip->actstart, 0.0);
1009                                                 
1010                                                 if(blocktype==ID_AR)
1011                                                         extract_pose_from_action (tpose, strip->act, frametime);
1012                                                 else if(blocktype==ID_OB) {
1013                                                         extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
1014                                                         if(key)
1015                                                                 extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
1016                                                 }
1017                                                 doit=1;
1018                                         }
1019                                 }
1020                                 
1021                                 /* Handle blendin & blendout */
1022                                 if (doit){
1023                                         /* Handle blendin */
1024                                         
1025                                         if (strip->blendin>0.0 && stripframe<=strip->blendin && scene_cfra>=strip->start){
1026                                                 blendfac = stripframe/strip->blendin;
1027                                         }
1028                                         else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && scene_cfra<=strip->end){
1029                                                 blendfac = (length-stripframe)/(strip->blendout);
1030                                         }
1031                                         else
1032                                                 blendfac = 1;
1033                                         
1034                                         if(blocktype==ID_AR) {/* Blend this pose with the accumulated pose */
1035                                                 blend_poses (ob->pose, tpose, blendfac, strip->mode);
1036                                                 if(dostride)
1037                                                         blend_pose_strides (ob->pose, tpose, blendfac, strip->mode);
1038                                         }
1039                                         else {
1040                                                 blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode);
1041                                                 BLI_freelistN(&tchanbase);
1042                                         }
1043                                 }
1044                         }                                       
1045                 }
1046         }
1047         
1048         if(blocktype==ID_OB) {
1049                 execute_ipochannels(&chanbase);
1050         }
1051         else if(blocktype==ID_AR) {
1052                 /* apply stride offset to object */
1053                 VecAddf(ob->obmat[3], ob->obmat[3], ob->pose->stride_offset);
1054         }
1055         
1056         /* free */
1057         if (tpose){
1058                 free_pose_channels(tpose);
1059                 MEM_freeN(tpose);
1060         }
1061         if(chanbase.first)
1062                 BLI_freelistN(&chanbase);
1063         
1064 }
1065
1066 void do_all_pose_actions(Object *ob)
1067 {
1068
1069         // only to have safe calls from editor
1070         if(ob==NULL) return;
1071         if(ob->type!=OB_ARMATURE || ob->pose==NULL) return;
1072
1073         if(ob->pose->flag & POSE_LOCKED) {  // no actions to execute while transform
1074                 if(ob->pose->flag & POSE_DO_UNLOCK)
1075                         ob->pose->flag &= ~(POSE_LOCKED|POSE_DO_UNLOCK);
1076         }
1077         else if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
1078                 float cframe= (float) G.scene->r.cfra;
1079                 
1080                 cframe= get_action_frame(ob, cframe);
1081                 
1082                 extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, cframe, 0.0));
1083         }
1084         else if(ob->nlastrips.first) {
1085                 do_nla(ob, ID_AR);
1086         }
1087 }
1088
1089 /* called from where_is_object */
1090 void do_all_object_actions(Object *ob)
1091 {
1092         if(ob==NULL) return;
1093         if(ob->dup_group) return;       /* prevent conflicts, might add smarter check later */
1094         
1095         /* Do local action */
1096         if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
1097                 ListBase tchanbase= {NULL, NULL};
1098                 Key *key= ob_get_key(ob);
1099                 float cframe= (float) G.scene->r.cfra;
1100                 
1101                 cframe= get_action_frame(ob, cframe);
1102                 
1103                 extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(ob, 0, cframe, 0.0));
1104                 if(key)
1105                         extract_ipochannels_from_action(&tchanbase, &key->id, ob->action, "Shape", bsystem_time(ob, 0, cframe, 0.0));
1106                 
1107                 if(tchanbase.first) {
1108                         execute_ipochannels(&tchanbase);
1109                         BLI_freelistN(&tchanbase);
1110                 }
1111         }
1112         else if(ob->nlastrips.first) {
1113                 do_nla(ob, ID_OB);
1114         }
1115 }
1116
1117