cf7ad67d179f825360a94c10fd2f540b7f15fe43
[blender.git] / source / blender / blenkernel / intern / ipo.c
1 /* ipo.c 
2  * 
3  * $Id$
4  *
5  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version. The Blender
11  * Foundation also sells licenses for use in proprietary software under
12  * the Blender License.  See http://www.blender.org/BL/ for information
13  * about this.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  *
24  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
25  * All rights reserved.
26  *
27  * The Original Code is: all of this file.
28  *
29  * Contributor(s): none yet.
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32  */
33
34 #include <math.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifdef WIN32
43 #include "BLI_winstuff.h"
44 #endif
45 #include "MEM_guardedalloc.h"
46
47 #include "DNA_ika_types.h"
48 #include "DNA_sequence_types.h"
49 #include "DNA_camera_types.h"
50 #include "DNA_sound_types.h"
51 #include "DNA_lamp_types.h"
52 #include "DNA_view3d_types.h"
53 #include "DNA_key_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_texture_types.h"
56 #include "DNA_material_types.h"
57 #include "DNA_object_types.h"
58 #include "DNA_curve_types.h"
59 #include "DNA_ipo_types.h"
60 #include "DNA_action_types.h"
61 #include "BLI_blenlib.h"
62 #include "BLI_arithb.h"
63
64 #include "BKE_bad_level_calls.h"
65 #include "BKE_utildefines.h"
66
67 #include "BKE_main.h"
68 #include "BKE_global.h"
69 #include "BKE_library.h"
70 #include "BKE_curve.h"
71 #include "BKE_object.h"
72 #include "BKE_blender.h"
73 #include "BKE_ipo.h"
74 #include "BKE_constraint.h"
75
76 #define SMALL -1.0e-10
77
78 /* This array concept was meant to make sure that defines such as OB_LOC_X
79    don't have to be enumerated, also for backward compatibility, future changes,
80    and to enable it all can be accessed with a for-next loop.
81 */
82
83 int co_ar[CO_TOTIPO]= {
84         CO_ENFORCE
85 };
86
87 int ob_ar[OB_TOTIPO]= {
88         OB_LOC_X, OB_LOC_Y, OB_LOC_Z, OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z, 
89         OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z, 
90         OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z, 
91         OB_LAY, OB_TIME, OB_EFF_X, OB_EFF_Y, OB_EFF_Z, OB_COL_A
92 };
93
94 int ac_ar[AC_TOTIPO]= {
95         AC_LOC_X, AC_LOC_Y, AC_LOC_Z,  
96          AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z,
97         AC_SIZE_X, AC_SIZE_Y, AC_SIZE_Z
98 };
99
100 int ma_ar[MA_TOTIPO]= {
101         MA_COL_R, MA_COL_G, MA_COL_B, 
102         MA_SPEC_R, MA_SPEC_G, MA_SPEC_B, 
103         MA_MIR_R, MA_MIR_G, MA_MIR_B, 
104         MA_REF, MA_ALPHA, MA_EMIT, MA_AMB, 
105         MA_SPEC, MA_HARD, MA_SPTR, MA_ANG, 
106         MA_MODE, MA_HASIZE, 
107         
108         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
109         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
110         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
111         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF
112 };
113
114 int seq_ar[SEQ_TOTIPO]= {
115         SEQ_FAC1
116 };
117
118 int cu_ar[CU_TOTIPO]= {
119         CU_SPEED
120 };
121
122 int key_ar[KEY_TOTIPO]= {
123         KEY_SPEED, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
124         11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
125         21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
126 };
127
128 int wo_ar[WO_TOTIPO]= {
129         WO_HOR_R, WO_HOR_G, WO_HOR_B, WO_ZEN_R, WO_ZEN_G, WO_ZEN_B, 
130         WO_EXPOS, WO_MISI, WO_MISTDI, WO_MISTSTA, WO_MISTHI,
131         WO_STAR_R, WO_STAR_G, WO_STAR_B, WO_STARDIST, WO_STARSIZE, 
132
133         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
134         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
135         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
136         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF
137 };
138
139 int la_ar[LA_TOTIPO]= {
140         LA_ENERGY,  LA_COL_R, LA_COL_G,  LA_COL_B, 
141         LA_DIST, LA_SPOTSI, LA_SPOTBL, 
142         LA_QUAD1,  LA_QUAD2,  LA_HALOINT,  
143
144         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
145         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
146         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
147         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF
148 };
149
150 int cam_ar[CAM_TOTIPO]= {
151         CAM_LENS, CAM_STA, CAM_END
152 };
153
154 int snd_ar[SND_TOTIPO]= {
155         SND_VOLUME, SND_PITCH, SND_PANNING, SND_ATTEN
156 };
157
158
159
160 float frame_to_float(int cfra)          /* see also bsystem_time in object.c */
161 {
162         extern float bluroffs;  /* object.c */
163         float ctime;
164         
165         ctime= (float)cfra;
166         if(R.flag & R_SEC_FIELD) {
167                 if((R.r.mode & R_FIELDSTILL)==0) ctime+= 0.5;
168         }
169         ctime+= bluroffs;
170         ctime*= G.scene->r.framelen;
171         
172         return ctime;
173 }
174
175 /* do not free ipo itself */
176 void free_ipo(Ipo *ipo)
177 {
178         IpoCurve *icu;
179         
180         icu= ipo->curve.first;
181         while(icu) {
182                 if(icu->bezt) MEM_freeN(icu->bezt);
183                 icu= icu->next;
184         }
185         BLI_freelistN(&ipo->curve);
186 }
187
188 Ipo *add_ipo(char *name, int idcode)
189 {
190         Ipo *ipo;
191         
192         ipo= alloc_libblock(&G.main->ipo, ID_IP, name);
193         ipo->blocktype= idcode;
194         
195         return ipo;
196 }
197
198 Ipo *copy_ipo(Ipo *ipo)
199 {
200         Ipo *ipon;
201         IpoCurve *icu;
202         
203         if(ipo==0) return 0;
204         
205         ipon= copy_libblock(ipo);
206         
207         duplicatelist(&(ipon->curve), &(ipo->curve));
208         
209         icu= ipon->curve.first;
210         while(icu) {
211                 icu->bezt= MEM_dupallocN(icu->bezt);
212                 icu= icu->next;
213         }
214         
215         return ipon;
216 }
217
218 void make_local_obipo(Ipo *ipo)
219 {
220         Object *ob;
221         Ipo *ipon;
222         int local=0, lib=0;
223         
224         /* - only lib users: do nothing
225          * - only local users: set flag
226          * - mixed: make copy
227          */
228
229         ob= G.main->object.first;
230         while(ob) {
231                 if(ob->ipo==ipo) {
232                         if(ob->id.lib) lib= 1;
233                         else local= 1;
234                 }
235                 ob= ob->id.next;
236         }
237         
238         if(local && lib==0) {
239                 ipo->id.lib= 0;
240                 ipo->id.flag= LIB_LOCAL;
241                 new_id(0, (ID *)ipo, 0);
242         }
243         else if(local && lib) {
244                 ipon= copy_ipo(ipo);
245                 ipon->id.us= 0;
246                 
247                 ob= G.main->object.first;
248                 while(ob) {
249                         if(ob->ipo==ipo) {
250                                 
251                                 if(ob->id.lib==0) {
252                                         ob->ipo= ipon;
253                                         ipon->id.us++;
254                                         ipo->id.us--;
255                                 }
256                         }
257                         ob= ob->id.next;
258                 }
259         }
260 }
261
262 void make_local_matipo(Ipo *ipo)
263 {
264         Material *ma;
265         Ipo *ipon;
266         int local=0, lib=0;
267
268         /* - only lib users: do nothing
269             * - only local users: set flag
270             * - mixed: make copy
271         */
272         
273         ma= G.main->mat.first;
274         while(ma) {
275                 if(ma->ipo==ipo) {
276                         if(ma->id.lib) lib= 1;
277                         else local= 1;
278                 }
279                 ma= ma->id.next;
280         }
281         
282         if(local && lib==0) {
283                 ipo->id.lib= 0;
284                 ipo->id.flag= LIB_LOCAL;
285                 new_id(0, (ID *)ipo, 0);
286         }
287         else if(local && lib) {
288                 ipon= copy_ipo(ipo);
289                 ipon->id.us= 0;
290                 
291                 ma= G.main->mat.first;
292                 while(ma) {
293                         if(ma->ipo==ipo) {
294                                 
295                                 if(ma->id.lib==0) {
296                                         ma->ipo= ipon;
297                                         ipon->id.us++;
298                                         ipo->id.us--;
299                                 }
300                         }
301                         ma= ma->id.next;
302                 }
303         }
304 }
305
306 void make_local_keyipo(Ipo *ipo)
307 {
308         Key *key;
309         Ipo *ipon;
310         int local=0, lib=0;
311
312         /* - only lib users: do nothing
313          * - only local users: set flag
314          * - mixed: make copy
315          */
316         
317         key= G.main->key.first;
318         while(key) {
319                 if(key->ipo==ipo) {
320                         if(key->id.lib) lib= 1;
321                         else local= 1;
322                 }
323                 key= key->id.next;
324         }
325         
326         if(local && lib==0) {
327                 ipo->id.lib= 0;
328                 ipo->id.flag= LIB_LOCAL;
329                 new_id(0, (ID *)ipo, 0);
330         }
331         else if(local && lib) {
332                 ipon= copy_ipo(ipo);
333                 ipon->id.us= 0;
334                 
335                 key= G.main->key.first;
336                 while(key) {
337                         if(key->ipo==ipo) {
338                                 
339                                 if(key->id.lib==0) {
340                                         key->ipo= ipon;
341                                         ipon->id.us++;
342                                         ipo->id.us--;
343                                 }
344                         }
345                         key= key->id.next;
346                 }
347         }
348 }
349
350
351 void make_local_ipo(Ipo *ipo)
352 {
353         
354         if(ipo->id.lib==0) return;
355         if(ipo->id.us==1) {
356                 ipo->id.lib= 0;
357                 ipo->id.flag= LIB_LOCAL;
358                 new_id(0, (ID *)ipo, 0);
359                 return;
360         }
361         
362         if(ipo->blocktype==ID_OB) make_local_obipo(ipo);
363         else if(ipo->blocktype==ID_MA) make_local_matipo(ipo);
364         else if(ipo->blocktype==ID_KE) make_local_keyipo(ipo);
365
366 }
367
368
369 void calchandles_ipocurve(IpoCurve *icu)
370 {
371         BezTriple *bezt, *prev, *next;
372         int a;
373
374         a= icu->totvert;
375         if(a<2) return;
376         
377         bezt= icu->bezt;
378         prev= 0;
379         next= bezt+1;
380
381         while(a--) {
382
383                 if(bezt->vec[0][0]>bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
384                 if(bezt->vec[2][0]<bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
385
386                 calchandleNurb(bezt, prev, next, 1);    /* 1==special autohandle */
387
388                 prev= bezt;
389                 if(a==1) {
390                         next= 0;
391                 }
392                 else next++;
393                         
394                 /* for automatic ease in and out */
395                 if(bezt->h1==HD_AUTO && bezt->h2==HD_AUTO) {
396                         if(a==0 || a==icu->totvert-1) {
397                                 if(icu->extrap==IPO_HORIZ) {
398                                         bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
399                                 }
400                         }
401                 }
402                 
403                 bezt++;
404         }
405 }
406
407 void testhandles_ipocurve(IpoCurve *icu)
408 {
409     /* use when something has changed with handles.
410     it treats all BezTriples with the following rules:
411     PHASE 1: do types have to be altered?
412      Auto handles: become aligned when selection status is NOT(000 || 111)
413      Vector handles: become 'nothing' when (one half selected AND other not)
414     PHASE 2: recalculate handles
415     */
416     BezTriple *bezt;
417         int flag, a;
418
419         bezt= icu->bezt;
420         if(bezt==0) return;
421         
422         a= icu->totvert;
423         while(a--) {
424                 flag= 0;
425                 if(bezt->f1 & 1) flag++;
426                 if(bezt->f2 & 1) flag += 2;
427                 if(bezt->f3 & 1) flag += 4;
428
429                 if( !(flag==0 || flag==7) ) {
430                         if(bezt->h1==HD_AUTO) {   /* auto */
431                                 bezt->h1= HD_ALIGN;
432                         }
433                         if(bezt->h2==HD_AUTO) {   /* auto */
434                                 bezt->h2= HD_ALIGN;
435                         }
436
437                         if(bezt->h1==HD_VECT) {   /* vector */
438                                 if(flag < 4) bezt->h1= 0;
439                         }
440                         if(bezt->h2==HD_VECT) {   /* vector */
441                                 if( flag > 3) bezt->h2= 0;
442                         }
443                 }
444                 bezt++;
445         }
446
447         calchandles_ipocurve(icu);
448 }
449
450
451 void sort_time_ipocurve(IpoCurve *icu)
452 {
453         BezTriple *bezt;
454         int a, ok= 1;
455         
456         while(ok) {
457                 ok= 0;
458
459                 if(icu->bezt) {
460                         bezt= icu->bezt;
461                         a= icu->totvert;
462                         while(a--) {
463                                 if(a>0) {
464                                         if( bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
465                                                 SWAP(BezTriple, *bezt, *(bezt+1));
466                                                 ok= 1;
467                                         }
468                                 }
469                                 if(bezt->vec[0][0]>=bezt->vec[1][0] && bezt->vec[2][0]<=bezt->vec[1][0]) {
470                                         SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
471                                         SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
472                                 }
473                                 else {
474                                         if(bezt->vec[0][0]>bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
475                                         if(bezt->vec[2][0]<bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
476                                 }
477                                 bezt++;
478                         }
479                 }
480                 else {
481                         
482                 }
483         }
484 }
485
486 int test_time_ipocurve(IpoCurve *icu)
487 {
488         BezTriple *bezt;
489         int a;
490         
491         if(icu->bezt) {
492                 bezt= icu->bezt;
493                 a= icu->totvert-1;
494                 while(a--) {
495                         if( bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
496                                 return 1;
497                         }
498                         bezt++;
499                 }       
500         }
501         else {
502                 
503         }
504
505         return 0;
506 }
507
508 void correct_bezpart(float *v1, float *v2, float *v3, float *v4)
509 {
510         /* the total length of the handles is not allowed to be more
511          * than the horizontal distance between (v1-v4)
512          * this to prevent curve loops
513          */
514         float h1[2], h2[2], len1, len2, len, fac;
515         
516         h1[0]= v1[0]-v2[0];
517         h1[1]= v1[1]-v2[1];
518         h2[0]= v4[0]-v3[0];
519         h2[1]= v4[1]-v3[1];
520         
521         len= v4[0]- v1[0];
522         len1= (float)fabs(h1[0]);
523         len2= (float)fabs(h2[0]);
524         
525         if(len1+len2==0.0) return;
526         if(len1+len2 > len) {
527                 fac= len/(len1+len2);
528                 
529                 v2[0]= (v1[0]-fac*h1[0]);
530                 v2[1]= (v1[1]-fac*h1[1]);
531                 
532                 v3[0]= (v4[0]-fac*h2[0]);
533                 v3[1]= (v4[1]-fac*h2[1]);
534                 
535         }
536 }
537
538 /* *********************** ARITH *********************** */
539
540 int findzero(float x, float q0, float q1, float q2, float q3, float *o)
541 {
542         double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
543         int nr= 0;
544
545         c0= q0-x;
546         c1= 3*(q1-q0);
547         c2= 3*(q0-2*q1+q2);
548         c3= q3-q0+3*(q1-q2);
549         
550         if(c3!=0.0) {
551                 a= c2/c3;
552                 b= c1/c3;
553                 c= c0/c3;
554                 a= a/3;
555
556                 p= b/3-a*a;
557                 q= (2*a*a*a-a*b+c)/2;
558                 d= q*q+p*p*p;
559
560                 if(d>0.0) {
561                         t= sqrt(d);
562                         o[0]= (float)(Sqrt3d(-q+t)+Sqrt3d(-q-t)-a);
563                         if(o[0]>= SMALL && o[0]<=1.000001) return 1;
564                         else return 0;
565                 }
566                 else if(d==0.0) {
567                         t= Sqrt3d(-q);
568                         o[0]= (float)(2*t-a);
569                         if(o[0]>=SMALL && o[0]<=1.000001) nr++;
570                         o[nr]= (float)(-t-a);
571                         if(o[nr]>=SMALL && o[nr]<=1.000001) return nr+1;
572                         else return nr;
573                 }
574                 else {
575                         phi= acos(-q/sqrt(-(p*p*p)));
576                         t= sqrt(-p);
577                         p= cos(phi/3);
578                         q= sqrt(3-3*p*p);
579                         o[0]= (float)(2*t*p-a);
580                         if(o[0]>=SMALL && o[0]<=1.000001) nr++;
581                         o[nr]= (float)(-t*(p+q)-a);
582                         if(o[nr]>=SMALL && o[nr]<=1.000001) nr++;
583                         o[nr]= (float)(-t*(p-q)-a);
584                         if(o[nr]>=SMALL && o[nr]<=1.000001) return nr+1;
585                         else return nr;
586                 }
587         }
588         else {
589                 a=c2;
590                 b=c1;
591                 c=c0;
592                 
593                 if(a!=0.0) {
594                         p=b*b-4*a*c;
595                         if(p>0) {
596                                 p= sqrt(p);
597                                 o[0]= (float)((-b-p)/(2*a));
598                                 if(o[0]>=SMALL && o[0]<=1.000001) nr++;
599                                 o[nr]= (float)((-b+p)/(2*a));
600                                 if(o[nr]>=SMALL && o[nr]<=1.000001) return nr+1;
601                                 else return nr;
602                         }
603                         else if(p==0) {
604                                 o[0]= (float)(-b/(2*a));
605                                 if(o[0]>=SMALL && o[0]<=1.000001) return 1;
606                                 else return 0;
607                         }
608                 }
609                 else if(b!=0.0) {
610                         o[0]= (float)(-c/b);
611                         if(o[0]>=SMALL && o[0]<=1.000001) return 1;
612                         else return 0;
613                 }
614                 else if(c==0.0) {
615                         o[0]= 0.0;
616                         return 1;
617                 }
618                 return 0;       
619         }
620 }
621
622 void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
623 {
624         float t, c0, c1, c2, c3;
625         int a;
626
627         c0= f1;
628         c1= 3.0f*(f2 - f1);
629         c2= 3.0f*(f1 - 2.0f*f2 + f3);
630         c3= f4 - f1 + 3.0f*(f2-f3);
631         
632         for(a=0; a<b; a++) {
633                 t= o[a];
634                 o[a]= c0+t*c1+t*t*c2+t*t*t*c3;
635         }
636 }
637 void berekenx(float *f, float *o, int b)
638 {
639         float t, c0, c1, c2, c3;
640         int a;
641
642         c0= f[0];
643         c1= 3*(f[3]-f[0]);
644         c2= 3*(f[0]-2*f[3]+f[6]);
645         c3= f[9]-f[0]+3*(f[3]-f[6]);
646         for(a=0; a<b; a++) {
647                 t= o[a];
648                 o[a]= c0+t*c1+t*t*c2+t*t*t*c3;
649         }
650 }
651
652 float eval_icu(IpoCurve *icu, float ipotime) 
653 {
654         BezTriple *bezt, *prevbezt;
655         float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
656         float cycdx, cycdy, ofs, cycyofs, cvalue = 0.0;
657         int a, b;
658         
659         cycyofs= 0.0;
660         
661         if(icu->bezt) {
662                 prevbezt= icu->bezt;
663                 bezt= prevbezt+1;
664                 a= icu->totvert-1;
665                 
666                 /* cyclic? */
667                 if(icu->extrap & IPO_CYCL) {
668                         ofs= icu->bezt->vec[1][0];
669                         cycdx= (icu->bezt+icu->totvert-1)->vec[1][0] - ofs;
670                         cycdy= (icu->bezt+icu->totvert-1)->vec[1][1] - icu->bezt->vec[1][1];
671                         if(cycdx!=0.0) {
672                                 
673                                 if(icu->extrap & IPO_DIR) {
674                                         cycyofs= (float)floor((ipotime-ofs)/cycdx);
675                                         cycyofs*= cycdy;
676                                 }
677
678                                 ipotime= (float)(fmod(ipotime-ofs, cycdx)+ofs);
679                                 if(ipotime<ofs) ipotime+= cycdx;
680                         }
681                 }
682                 
683                 /* endpoints? */
684         
685                 if(prevbezt->vec[1][0]>=ipotime) {
686                         if( (icu->extrap & IPO_DIR) && icu->ipo!=IPO_CONST) {
687                                 dx= prevbezt->vec[1][0]-ipotime;
688                                 fac= prevbezt->vec[1][0]-prevbezt->vec[0][0];
689                                 if(fac!=0.0) {
690                                         fac= (prevbezt->vec[1][1]-prevbezt->vec[0][1])/fac;
691                                         cvalue= prevbezt->vec[1][1]-fac*dx;
692                                 }
693                                 else cvalue= prevbezt->vec[1][1];
694                         }
695                         else cvalue= prevbezt->vec[1][1];
696                         
697                         cvalue+= cycyofs;
698                 }
699                 else if( (prevbezt+a)->vec[1][0]<=ipotime) {
700                         if( (icu->extrap & IPO_DIR) && icu->ipo!=IPO_CONST) {
701                                 prevbezt+= a;
702                                 dx= ipotime-prevbezt->vec[1][0];
703                                 fac= prevbezt->vec[2][0]-prevbezt->vec[1][0];
704                                 
705                                 if(fac!=0) {
706                                         fac= (prevbezt->vec[2][1]-prevbezt->vec[1][1])/fac;
707                                         cvalue= prevbezt->vec[1][1]+fac*dx;
708                                 }
709                                 else cvalue= prevbezt->vec[1][1];
710                         }
711                         else cvalue= (prevbezt+a)->vec[1][1];
712                         
713                         cvalue+= cycyofs;
714                 }
715                 else {
716                         while(a--) {
717                                 if(prevbezt->vec[1][0]<=ipotime && bezt->vec[1][0]>=ipotime) {
718                                         if(icu->ipo==IPO_CONST) {
719                                                 cvalue= prevbezt->vec[1][1]+cycyofs;
720                                         }
721                                         else if(icu->ipo==IPO_LIN) {
722                                                 fac= bezt->vec[1][0]-prevbezt->vec[1][0];
723                                                 if(fac==0) cvalue= cycyofs+prevbezt->vec[1][1];
724                                                 else {
725                                                         fac= (ipotime-prevbezt->vec[1][0])/fac;
726                                                         cvalue= cycyofs+prevbezt->vec[1][1]+ fac*(bezt->vec[1][1]-prevbezt->vec[1][1]);
727                                                 }
728                                         }
729                                         else {
730                                                 v1[0]= prevbezt->vec[1][0];
731                                                 v1[1]= prevbezt->vec[1][1];
732                                                 v2[0]= prevbezt->vec[2][0];
733                                                 v2[1]= prevbezt->vec[2][1];
734                                                 
735                                                 v3[0]= bezt->vec[0][0];
736                                                 v3[1]= bezt->vec[0][1];
737                                                 v4[0]= bezt->vec[1][0];
738                                                 v4[1]= bezt->vec[1][1];
739
740                                                 correct_bezpart(v1, v2, v3, v4);
741                                                 
742                                                 b= findzero(ipotime, v1[0], v2[0], v3[0], v4[0], opl);
743                                                 if(b) {
744                                                         berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
745                                                         cvalue= opl[0]+cycyofs;
746                                                         break;
747                                                 }
748                                         }
749                                 }
750                                 prevbezt= bezt;
751                                 bezt++;
752                         }
753                 }
754         }
755
756         if(icu->ymin < icu->ymax) {
757                 if(cvalue < icu->ymin) cvalue= icu->ymin;
758                 else if(cvalue > icu->ymax) cvalue= icu->ymax;
759         }
760         
761         return cvalue;
762 }
763
764 void calc_icu(IpoCurve *icu, float ctime)
765 {
766         icu->curval= eval_icu(icu, ctime);
767 }
768
769 float calc_ipo_time(Ipo *ipo, float ctime)
770 {
771
772         if(ipo && ipo->blocktype==ID_OB) {
773                 IpoCurve *icu= ipo->curve.first;
774
775                 while(icu) {
776                         if (icu->adrcode==OB_TIME) {
777                                 calc_icu(icu, ctime);
778                                 return 10.0f*icu->curval;
779                         }
780                         icu= icu->next;
781                 }       
782         }
783         
784         return ctime;
785 }
786
787 void calc_ipo(Ipo *ipo, float ctime)
788 {
789         IpoCurve *icu;
790         
791         icu= ipo->curve.first;
792         while(icu) {
793                 
794                 if( (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime);
795                 
796                 icu= icu->next;
797         }
798 }
799
800 /* ************************************** */
801 /*              DO THE IPO!                                               */
802 /* ************************************** */
803
804 void write_ipo_poin(void *poin, int type, float val)
805 {
806
807         switch(type) {
808         case IPO_FLOAT:
809                 *( (float *)poin)= val;
810                 break;
811         case IPO_FLOAT_DEGR:
812                 *( (float *)poin)= (float)(val*M_PI_2/9.0);
813                 break;
814         case IPO_INT:
815         case IPO_INT_BIT:
816         case IPO_LONG:
817                 *( (int *)poin)= (int)val;
818                 break;
819         case IPO_SHORT:
820         case IPO_SHORT_BIT:
821                 *( (short *)poin)= (short)val;
822                 break;
823         case IPO_CHAR:
824         case IPO_CHAR_BIT:
825                 *( (char *)poin)= (char)val;
826                 break;
827         }
828 }
829
830 float read_ipo_poin(void *poin, int type)
831 {
832         float val = 0.0;
833         
834         switch(type) {
835         case IPO_FLOAT:
836                 val= *( (float *)poin);
837                 break;
838         case IPO_FLOAT_DEGR:
839                 val= *( (float *)poin);
840                 val = (float)(val/(M_PI_2/9.0));
841                 break;
842         case IPO_INT:
843         case IPO_INT_BIT:
844         case IPO_LONG:
845                 val= (float)(*( (int *)poin));
846                 break;
847         case IPO_SHORT:
848         case IPO_SHORT_BIT:
849                 val= *( (short *)poin);
850                 break;
851         case IPO_CHAR:
852         case IPO_CHAR_BIT:
853                 val= *( (char *)poin);
854                 break;
855         }
856         return val;
857 }
858
859 void *give_mtex_poin(MTex *mtex, int adrcode )
860 {
861         void *poin=0;
862                 
863         switch(adrcode) {
864         case MAP_OFS_X:
865                 poin= &(mtex->ofs[0]); break;
866         case MAP_OFS_Y:
867                 poin= &(mtex->ofs[1]); break;
868         case MAP_OFS_Z:
869                 poin= &(mtex->ofs[2]); break;
870         case MAP_SIZE_X:
871                 poin= &(mtex->size[0]); break;
872         case MAP_SIZE_Y:
873                 poin= &(mtex->size[1]); break;
874         case MAP_SIZE_Z:
875                 poin= &(mtex->size[2]); break;
876         case MAP_R:
877                 poin= &(mtex->r); break;
878         case MAP_G:
879                 poin= &(mtex->g); break;
880         case MAP_B:
881                 poin= &(mtex->b); break;
882         case MAP_DVAR:
883                 poin= &(mtex->def_var); break;
884         case MAP_COLF:
885                 poin= &(mtex->colfac); break;
886         case MAP_NORF:
887                 poin= &(mtex->norfac); break;
888         case MAP_VARF:
889                 poin= &(mtex->varfac); break;
890         }
891         
892         return poin;
893 }
894
895 /* GS reads the memory pointed at in a specific ordering. There are,
896  * however two definitions for it. I have jotted them down here, both,
897  * but I think the first one is actually used. The thing is that
898  * big-endian systems might read this the wrong way round. OTOH, we
899  * constructed the IDs that are read out with this macro explicitly as
900  * well. I expect we'll sort it out soon... */
901
902 /* from blendef: */
903 #define GS(a)   (*((short *)(a)))
904
905 /* from misc_util: flip the bytes from x  */
906 /*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
907
908 void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
909 {
910         void *poin= 0;
911         Object *ob;
912         Material *ma;
913         MTex *mtex;
914         Ika *ika= 0;
915         Lamp *la;
916         Sequence *seq;
917         World *wo;
918         bAction                 *act;
919         bActionChannel  *achan;
920         bPoseChannel    *pchan;
921
922         *type= IPO_FLOAT;
923
924
925         if( GS(id->name)==ID_OB) {
926         
927                 ob= (Object *)id;
928
929                 if(ob->type==OB_IKA) ika= ob->data;
930                 
931                 switch(icu->adrcode) {
932                 case OB_LOC_X:
933                         poin= &(ob->loc[0]); break;
934                 case OB_LOC_Y:
935                         poin= &(ob->loc[1]); break;
936                 case OB_LOC_Z:
937                         poin= &(ob->loc[2]); break;
938                 case OB_DLOC_X:
939                         poin= &(ob->dloc[0]); break;
940                 case OB_DLOC_Y:
941                         poin= &(ob->dloc[1]); break;
942                 case OB_DLOC_Z:
943                         poin= &(ob->dloc[2]); break;
944         
945                 case OB_ROT_X:
946                         poin= &(ob->rot[0]); *type= IPO_FLOAT_DEGR; break;
947                 case OB_ROT_Y:
948                         poin= &(ob->rot[1]); *type= IPO_FLOAT_DEGR; break;
949                 case OB_ROT_Z:
950                         poin= &(ob->rot[2]); *type= IPO_FLOAT_DEGR; break;
951                 case OB_DROT_X:
952                         poin= &(ob->drot[0]); *type= IPO_FLOAT_DEGR; break;
953                 case OB_DROT_Y:
954                         poin= &(ob->drot[1]); *type= IPO_FLOAT_DEGR; break;
955                 case OB_DROT_Z:
956                         poin= &(ob->drot[2]); *type= IPO_FLOAT_DEGR; break;
957                         
958                 case OB_SIZE_X:
959                         poin= &(ob->size[0]); break;
960                 case OB_SIZE_Y:
961                         poin= &(ob->size[1]); break;
962                 case OB_SIZE_Z:
963                         poin= &(ob->size[2]); break;
964                 case OB_DSIZE_X:
965                         poin= &(ob->dsize[0]); break;
966                 case OB_DSIZE_Y:
967                         poin= &(ob->dsize[1]); break;
968                 case OB_DSIZE_Z:
969                         poin= &(ob->dsize[2]); break;
970                 
971                 case OB_LAY:
972                         poin= &(ob->lay); *type= IPO_INT_BIT; break;
973                         
974                 case OB_EFF_X:  /* OB_COL_R */
975                         if(ika) poin= &(ika->effg[0]);
976                         else poin= &(ob->col[0]);
977                         break;
978                 case OB_EFF_Y:  /* OB_COL_G */
979                         if(ika) poin= &(ika->effg[1]);
980                         else poin= &(ob->col[1]);
981                         break;
982                 case OB_EFF_Z:  /* OB_COL_B */
983                         if(ika) poin= &(ika->effg[2]);
984                         else poin= &(ob->col[2]);
985                         break;
986                 case OB_COL_A:
987                         poin= &(ob->col[3]);
988                         break;
989                 }
990         }
991         else if (GS(id->name)==ID_AC){
992                 act= (bAction *)id;
993                 achan = act->achan;
994                 pchan = act->pchan;
995                 if (!pchan || !achan)
996                         return NULL;
997                 switch (icu->adrcode){
998                 case AC_QUAT_W:
999                         poin= &(pchan->quat[0]); break;
1000                 case AC_QUAT_X:
1001                         poin= &(pchan->quat[1]); break;
1002                 case AC_QUAT_Y:
1003                         poin= &(pchan->quat[2]); break;
1004                 case AC_QUAT_Z:
1005                         poin= &(pchan->quat[3]); break;
1006                 case AC_LOC_X:
1007                         poin= &(pchan->loc[0]); break;
1008                 case AC_LOC_Y:
1009                         poin= &(pchan->loc[1]); break;
1010                 case AC_LOC_Z:
1011                         poin= &(pchan->loc[2]); break;                  
1012                 case AC_SIZE_X:
1013                         poin= &(pchan->size[0]); break;
1014                 case AC_SIZE_Y:
1015                         poin= &(pchan->size[1]); break;
1016                 case AC_SIZE_Z:
1017                         poin= &(pchan->size[2]); break;
1018                 };
1019         }
1020
1021         else if( GS(id->name)==ID_MA) {
1022                 
1023                 ma= (Material *)id;
1024                 
1025                 switch(icu->adrcode) {
1026                 case MA_COL_R:
1027                         poin= &(ma->r); break;
1028                 case MA_COL_G:
1029                         poin= &(ma->g); break;
1030                 case MA_COL_B:
1031                         poin= &(ma->b); break;
1032                 case MA_SPEC_R:
1033                         poin= &(ma->specr); break;
1034                 case MA_SPEC_G:
1035                         poin= &(ma->specg); break;
1036                 case MA_SPEC_B:
1037                         poin= &(ma->specb); break;
1038                 case MA_MIR_R:
1039                         poin= &(ma->mirr); break;
1040                 case MA_MIR_G:
1041                         poin= &(ma->mirg); break;
1042                 case MA_MIR_B:
1043                         poin= &(ma->mirb); break;
1044                 case MA_REF:
1045                         poin= &(ma->ref); break;
1046                 case MA_ALPHA:
1047                         poin= &(ma->alpha); break;
1048                 case MA_EMIT:
1049                         poin= &(ma->emit); break;
1050                 case MA_AMB:
1051                         poin= &(ma->amb); break;
1052                 case MA_SPEC:
1053                         poin= &(ma->spec); break;
1054                 case MA_HARD:
1055                         poin= &(ma->har); *type= IPO_SHORT; break;
1056                 case MA_SPTR:
1057                         poin= &(ma->spectra); break;
1058                 case MA_ANG:
1059                         poin= &(ma->ang); break;
1060                 case MA_MODE:
1061                         poin= &(ma->mode); *type= IPO_INT_BIT; break;
1062                 case MA_HASIZE:
1063                         poin= &(ma->hasize); break;
1064                 }
1065                 
1066                 if(poin==0) {
1067                         mtex= 0;
1068                         if(icu->adrcode & MA_MAP1) mtex= ma->mtex[0];
1069                         else if(icu->adrcode & MA_MAP2) mtex= ma->mtex[1];
1070                         else if(icu->adrcode & MA_MAP3) mtex= ma->mtex[2];
1071                         else if(icu->adrcode & MA_MAP4) mtex= ma->mtex[3];
1072                         else if(icu->adrcode & MA_MAP5) mtex= ma->mtex[4];
1073                         else if(icu->adrcode & MA_MAP6) mtex= ma->mtex[5];
1074                         else if(icu->adrcode & MA_MAP7) mtex= ma->mtex[6];
1075                         else if(icu->adrcode & MA_MAP8) mtex= ma->mtex[7];
1076                         
1077                         if(mtex) {
1078                                 poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
1079                         }
1080                 }
1081         }
1082         else if( GS(id->name)==ID_SEQ) {
1083                 seq= (Sequence *)id;
1084                 
1085                 switch(icu->adrcode) {
1086                 case SEQ_FAC1:
1087                         poin= &(seq->facf0); break;
1088                 }
1089         }
1090         else if( GS(id->name)==ID_CU) {
1091                 
1092                 poin= &(icu->curval);
1093                 
1094         }
1095         else if( GS(id->name)==ID_KE) {
1096                 
1097                 poin= &(icu->curval);
1098                 
1099         }
1100         else if(GS(id->name)==ID_WO) {
1101                 
1102                 wo= (World *)id;
1103                 
1104                 switch(icu->adrcode) {
1105                 case WO_HOR_R:
1106                         poin= &(wo->horr); break;
1107                 case WO_HOR_G:
1108                         poin= &(wo->horg); break;
1109                 case WO_HOR_B:
1110                         poin= &(wo->horb); break;
1111                 case WO_ZEN_R:
1112                         poin= &(wo->zenr); break;
1113                 case WO_ZEN_G:
1114                         poin= &(wo->zeng); break;
1115                 case WO_ZEN_B:
1116                         poin= &(wo->zenb); break;
1117
1118                 case WO_EXPOS:
1119                         poin= &(wo->exposure); break;
1120
1121                 case WO_MISI:
1122                         poin= &(wo->misi); break;
1123                 case WO_MISTDI:
1124                         poin= &(wo->mistdist); break;
1125                 case WO_MISTSTA:
1126                         poin= &(wo->miststa); break;
1127                 case WO_MISTHI:
1128                         poin= &(wo->misthi); break;
1129
1130                 case WO_STAR_R:
1131                         poin= &(wo->starr); break;
1132                 case WO_STAR_G:
1133                         poin= &(wo->starg); break;
1134                 case WO_STAR_B:
1135                         poin= &(wo->starb); break;
1136
1137                 case WO_STARDIST:
1138                         poin= &(wo->stardist); break;
1139                 case WO_STARSIZE:
1140                         poin= &(wo->starsize); break;
1141                 }
1142
1143                 if(poin==0) {
1144                         mtex= 0;
1145                         if(icu->adrcode & MA_MAP1) mtex= wo->mtex[0];
1146                         else if(icu->adrcode & MA_MAP2) mtex= wo->mtex[1];
1147                         else if(icu->adrcode & MA_MAP3) mtex= wo->mtex[2];
1148                         else if(icu->adrcode & MA_MAP4) mtex= wo->mtex[3];
1149                         else if(icu->adrcode & MA_MAP5) mtex= wo->mtex[4];
1150                         else if(icu->adrcode & MA_MAP6) mtex= wo->mtex[5];
1151                         else if(icu->adrcode & MA_MAP7) mtex= wo->mtex[6];
1152                         else if(icu->adrcode & MA_MAP8) mtex= wo->mtex[7];
1153                         
1154                         if(mtex) {
1155                                 poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
1156                         }
1157                 }
1158         }
1159         else if( GS(id->name)==ID_LA) {
1160                 
1161                 la= (Lamp *)id;
1162         
1163                 switch(icu->adrcode) {
1164                 case LA_ENERGY:
1165                         poin= &(la->energy); break;             
1166                 case LA_COL_R:
1167                         poin= &(la->r); break;
1168                 case LA_COL_G:
1169                         poin= &(la->g); break;
1170                 case LA_COL_B:
1171                         poin= &(la->b); break;
1172                 case LA_DIST:
1173                         poin= &(la->dist); break;               
1174                 case LA_SPOTSI:
1175                         poin= &(la->spotsize); break;
1176                 case LA_SPOTBL:
1177                         poin= &(la->spotblend); break;
1178                 case LA_QUAD1:
1179                         poin= &(la->att1); break;
1180                 case LA_QUAD2:
1181                         poin= &(la->att2); break;
1182                 case LA_HALOINT:
1183                         poin= &(la->haint); break;
1184                 }
1185                 
1186                 if(poin==0) {
1187                         mtex= 0;
1188                         if(icu->adrcode & MA_MAP1) mtex= la->mtex[0];
1189                         else if(icu->adrcode & MA_MAP2) mtex= la->mtex[1];
1190                         else if(icu->adrcode & MA_MAP3) mtex= la->mtex[2];
1191                         else if(icu->adrcode & MA_MAP4) mtex= la->mtex[3];
1192                         else if(icu->adrcode & MA_MAP5) mtex= la->mtex[4];
1193                         else if(icu->adrcode & MA_MAP6) mtex= la->mtex[5];
1194                         else if(icu->adrcode & MA_MAP7) mtex= la->mtex[6];
1195                         else if(icu->adrcode & MA_MAP8) mtex= la->mtex[7];
1196                         
1197                         if(mtex) {
1198                                 poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
1199                         }
1200                 }
1201         }
1202         else if(GS(id->name)==ID_CA) {
1203                 Camera *ca= (Camera *)id;
1204                 
1205                 switch(icu->adrcode) {
1206                 case CAM_LENS:
1207                         poin= &(ca->lens); break;
1208                 case CAM_STA:
1209                         poin= &(ca->clipsta); break;
1210                 case CAM_END:
1211                         poin= &(ca->clipend); break;
1212                 }
1213         }
1214         else if(GS(id->name)==ID_SO) {
1215                 bSound *snd= (bSound *)id;
1216                 
1217                 switch(icu->adrcode) {
1218                 case SND_VOLUME:
1219                         poin= &(snd->volume); break;
1220                 case SND_PITCH:
1221                         poin= &(snd->pitch); break;
1222                 case SND_PANNING:
1223                         poin= &(snd->panning); break;
1224                 case SND_ATTEN:
1225                         poin= &(snd->attenuation); break;
1226                 }
1227         }
1228         
1229         return poin;
1230 }
1231
1232 void set_icu_vars(IpoCurve *icu)
1233 {
1234         
1235         icu->ymin= icu->ymax= 0.0;
1236         icu->ipo= IPO_BEZ;
1237         
1238         if(icu->blocktype==ID_OB) {
1239         
1240                 if(icu->adrcode==OB_LAY) {
1241                         icu->ipo= IPO_CONST;
1242                         icu->vartype= IPO_BITS;
1243                 }
1244                 
1245         }
1246         else if(icu->blocktype==ID_MA) {
1247                 
1248                 if(icu->adrcode < MA_MAP1) {
1249                         switch(icu->adrcode) {
1250                         case MA_HASIZE:
1251                                 icu->ymax= 10000.0; break;
1252                         case MA_HARD:
1253                                 icu->ymax= 128.0; break;
1254                         case MA_SPEC:
1255                                 icu->ymax= 2.0; break;
1256                         case MA_MODE:
1257                                 icu->ipo= IPO_CONST;
1258                                 icu->vartype= IPO_BITS;
1259                                 break;
1260                                 
1261                         default:
1262                                 icu->ymax= 1.0;
1263                                 break;
1264                         }
1265                 }
1266                 else {
1267                         switch(icu->adrcode & (MA_MAP1-1)) {
1268                         case MAP_OFS_X:
1269                         case MAP_OFS_Y:
1270                         case MAP_OFS_Z:
1271                         case MAP_SIZE_X:
1272                         case MAP_SIZE_Y:
1273                         case MAP_SIZE_Z:
1274                                 icu->ymax= 1000.0;
1275                                 icu->ymin= -1000.0;
1276                         
1277                                 break;
1278                         case MAP_R:
1279                         case MAP_G:
1280                         case MAP_B:
1281                         case MAP_DVAR:
1282                         case MAP_COLF:
1283                         case MAP_VARF:
1284                                 icu->ymax= 1.0;
1285                                 break;
1286                         case MAP_NORF:
1287                                 icu->ymax= 5.0;
1288                                 break;
1289                         }
1290                 }
1291         }
1292         else if(icu->blocktype==ID_SEQ) {
1293         
1294                 icu->ymax= 1.0;
1295                 
1296         }
1297         else if(icu->blocktype==ID_CU) {
1298         
1299                 icu->ymax= 1.0;
1300                 
1301         }
1302         else if(icu->blocktype==ID_WO) {
1303                 
1304                 if(icu->adrcode < MA_MAP1) {
1305                         switch(icu->adrcode) {
1306                         case WO_EXPOS:
1307                                 icu->ymax= 5.0; break;
1308                         case WO_MISTDI:
1309                         case WO_MISTSTA:
1310                         case WO_MISTHI:
1311                         case WO_STARDIST:
1312                         case WO_STARSIZE:
1313                                 break;
1314                                 
1315                         default:
1316                                 icu->ymax= 1.0;
1317                                 break;
1318                         }
1319                 }
1320                 else {
1321                         switch(icu->adrcode & (MA_MAP1-1)) {
1322                         case MAP_OFS_X:
1323                         case MAP_OFS_Y:
1324                         case MAP_OFS_Z:
1325                         case MAP_SIZE_X:
1326                         case MAP_SIZE_Y:
1327                         case MAP_SIZE_Z:
1328                                 icu->ymax= 100.0;
1329                                 icu->ymin= -100.0;
1330                         
1331                                 break;
1332                         case MAP_R:
1333                         case MAP_G:
1334                         case MAP_B:
1335                         case MAP_DVAR:
1336                         case MAP_COLF:
1337                         case MAP_NORF:
1338                         case MAP_VARF:
1339                                 icu->ymax= 1.0;
1340                         }
1341                 }
1342         }
1343         else if(icu->blocktype==ID_LA) {
1344                 if(icu->adrcode < MA_MAP1) {
1345                         switch(icu->adrcode) {
1346                         case LA_ENERGY:
1347                         case LA_DIST:
1348                                 break;          
1349         
1350                         case LA_COL_R:
1351                         case LA_COL_G:
1352                         case LA_COL_B:
1353                         case LA_SPOTBL:
1354                         case LA_QUAD1:
1355                         case LA_QUAD2:
1356                                 icu->ymax= 1.0; break;
1357                         case LA_SPOTSI:
1358                                 icu->ymax= 180.0; break;
1359                         case LA_HALOINT:
1360                                 icu->ymax= 5.0; break;
1361                         }
1362                 }
1363                 else {
1364                         switch(icu->adrcode & (MA_MAP1-1)) {
1365                         case MAP_OFS_X:
1366                         case MAP_OFS_Y:
1367                         case MAP_OFS_Z:
1368                         case MAP_SIZE_X:
1369                         case MAP_SIZE_Y:
1370                         case MAP_SIZE_Z:
1371                                 icu->ymax= 100.0;
1372                                 icu->ymin= -100.0;
1373                                 break;
1374                         case MAP_R:
1375                         case MAP_G:
1376                         case MAP_B:
1377                         case MAP_DVAR:
1378                         case MAP_COLF:
1379                         case MAP_NORF:
1380                         case MAP_VARF:
1381                                 icu->ymax= 1.0;
1382                         }
1383                 }
1384         }       
1385         else if(icu->blocktype==ID_CA) {
1386
1387                 switch(icu->adrcode) {
1388                 case CAM_LENS:
1389                         icu->ymin= 5.0;
1390                         icu->ymax= 1000.0; break;
1391                 case CAM_STA:
1392                         icu->ymin= 0.001f;
1393                         break;
1394                 case CAM_END:
1395                         icu->ymin= 0.1f;
1396                 }
1397         }
1398         else if(icu->blocktype==ID_SO) {
1399
1400                 switch(icu->adrcode) {
1401                 case SND_VOLUME:
1402                         icu->ymin= 0.0;
1403                         icu->ymax= 1.0;
1404                         break;
1405                 case SND_PITCH:
1406                         icu->ymin= -12.0;
1407                         icu->ymin= 12.0;
1408                         break;
1409                 case SND_PANNING:
1410                         icu->ymin= 0.0;
1411                         icu->ymax= 1.0;
1412                         break;
1413                 case SND_ATTEN:
1414                         icu->ymin= 0.0;
1415                         icu->ymin= 1.0;
1416                         break;
1417                 }
1418         }
1419 }
1420
1421
1422 void execute_ipo(ID *id, Ipo *ipo)
1423 {
1424         IpoCurve *icu;
1425         void *poin;
1426         int type;
1427         
1428         if(ipo==0) return;
1429         
1430         icu= ipo->curve.first;
1431         while(icu) {
1432                 poin= get_ipo_poin(id, icu, &type);
1433                 if(poin) write_ipo_poin(poin, type, icu->curval);
1434                 icu= icu->next;
1435         }
1436 }
1437
1438 /* exception: it does calc for objects...
1439  * now find out why this routine was used anyway!
1440  */
1441 void do_ipo_nocalc(Ipo *ipo)
1442 {
1443         Object *ob;
1444         Material *ma;
1445         World *wo;
1446         Lamp *la;
1447         Camera *ca;
1448         bSound *snd;
1449         
1450         if(ipo==0) return;
1451         
1452         switch(ipo->blocktype) {
1453         case ID_OB:
1454                 ob= G.main->object.first;
1455                 while(ob) {
1456                         if(ob->ipo==ipo) {
1457                                 do_ob_ipo(ob);
1458                                 /* execute_ipo((ID *)ob, ipo); */
1459                         }
1460                         ob= ob->id.next;
1461                 }
1462                 break;
1463         case ID_MA:
1464                 ma= G.main->mat.first;
1465                 while(ma) {
1466                         if(ma->ipo==ipo) execute_ipo((ID *)ma, ipo);
1467                         ma= ma->id.next;
1468                 }
1469                 break;
1470         case ID_WO:
1471                 wo= G.main->world.first;
1472                 while(wo) {
1473                         if(wo->ipo==ipo) execute_ipo((ID *)wo, ipo);
1474                         wo= wo->id.next;
1475                 }
1476                 break;
1477         case ID_LA:
1478                 la= G.main->lamp.first;
1479                 while(la) {
1480                         if(la->ipo==ipo) execute_ipo((ID *)la, ipo);
1481                         la= la->id.next;
1482                 }
1483                 break;
1484         case ID_CA:
1485                 ca= G.main->camera.first;
1486                 while(ca) {
1487                         if(ca->ipo==ipo) execute_ipo((ID *)ca, ipo);
1488                         ca= ca->id.next;
1489                 }
1490                 break;
1491         case ID_SO:
1492                 snd= G.main->sound.first;
1493                 while(snd) {
1494                         if(snd->ipo==ipo) execute_ipo((ID *)snd, ipo);
1495                         snd= snd->id.next;
1496                 }
1497                 break;
1498         }
1499 }
1500
1501 void do_ipo(Ipo *ipo)
1502 {
1503         if(ipo) {
1504                 float ctime= frame_to_float(G.scene->r.cfra);
1505                 calc_ipo(ipo, ctime);
1506         
1507                 do_ipo_nocalc(ipo);
1508         }
1509 }
1510
1511
1512
1513 void do_mat_ipo(Material *ma)
1514 {
1515         float ctime;
1516         
1517         if(ma==0 || ma->ipo==0) return;
1518         
1519         ctime= frame_to_float(G.scene->r.cfra);
1520         /* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */
1521
1522         calc_ipo(ma->ipo, ctime);
1523         
1524         execute_ipo((ID *)ma, ma->ipo);
1525 }
1526
1527 void do_ob_ipo(Object *ob)
1528 {
1529         float ctime;
1530         unsigned int lay;
1531         
1532         if(ob->ipo==0) return;
1533
1534         /* do not set ob->ctime here: for example when parent in invisible layer */
1535         
1536         ctime= bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0);
1537
1538         calc_ipo(ob->ipo, ctime);
1539
1540         /* Patch: remember localview */
1541         lay= ob->lay & 0xFF000000;
1542         
1543         execute_ipo((ID *)ob, ob->ipo);
1544
1545         ob->lay |= lay;
1546         if(ob->id.name[2]=='S' && ob->id.name[3]=='C' && ob->id.name[4]=='E') {
1547                 if(strcmp(G.scene->id.name+2, ob->id.name+6)==0) {
1548                         G.scene->lay= ob->lay;
1549                         copy_view3d_lock(0);
1550                         /* no redraw here! creates too many calls */
1551                 }
1552         }
1553 }
1554
1555 void do_seq_ipo(Sequence *seq)
1556 {
1557         float ctime, div;
1558         
1559         /* seq_ipo has an exception: calc both fields immediately */
1560         
1561         if(seq->ipo) {
1562                 ctime= frame_to_float(G.scene->r.cfra - seq->startdisp);
1563                 div= (seq->enddisp - seq->startdisp)/100.0f;
1564                 if(div==0) return;
1565                 
1566                 /* 2nd field */
1567                 calc_ipo(seq->ipo, (ctime+0.5f)/div);
1568                 execute_ipo((ID *)seq, seq->ipo);
1569                 seq->facf1= seq->facf0;
1570
1571                 /* 1st field */
1572                 calc_ipo(seq->ipo, ctime/div);
1573                 execute_ipo((ID *)seq, seq->ipo);
1574
1575         }
1576         else seq->facf1= seq->facf0= 1.0f;
1577 }
1578
1579 int has_ipo_code(Ipo *ipo, int code)
1580 {
1581         IpoCurve *icu;
1582         
1583         if(ipo==0) return 0;
1584         
1585         icu= ipo->curve.first;
1586         while(icu) {
1587         
1588                 if(icu->adrcode==code) return 1;
1589                 
1590                 icu= icu->next;
1591         }
1592         return 0;
1593 }
1594
1595 void do_all_ipos()
1596 {
1597         Base *base;
1598         Material *ma;
1599         World *wo;
1600         Ipo *ipo;
1601         Lamp *la;
1602         Camera *ca;
1603         bSound *snd;
1604         Sequence *seq;
1605         Editing *ed;
1606         float ctime;
1607         int set;
1608
1609         ctime= frame_to_float(G.scene->r.cfra);
1610         
1611         ipo= G.main->ipo.first;
1612         while(ipo) {
1613                 if(ipo->id.us && ipo->blocktype!=ID_OB) {
1614                         calc_ipo(ipo, ctime);
1615                 }
1616                 ipo= ipo->id.next;
1617         }
1618
1619         /* NEW: current scene ob ipo's */
1620         base= G.scene->base.first;
1621         set= 0;
1622         while(base) {
1623
1624                 /* Do object ipos */
1625                 do_constraint_channels(&base->object->constraints, &base->object->constraintChannels, ctime);
1626
1627                 if(base->object->ipo) {
1628                         /* do per object ipo the calc_ipo: because of possible timeoffs */
1629                         do_ob_ipo(base->object);
1630                         if(base->object->type==OB_MBALL) where_is_object(base->object);
1631                 }
1632                 base= base->next;
1633                 
1634                 if(base==0 && set==0 && G.scene->set) {
1635                         set= 1;
1636                         base= G.scene->set->base.first;
1637                 }
1638         }
1639
1640         ma= G.main->mat.first;
1641         while(ma) {
1642                 if(ma->ipo) execute_ipo((ID *)ma, ma->ipo);
1643                 ma= ma->id.next;
1644         }
1645
1646         wo= G.main->world.first;
1647         while(wo) {
1648                 if(wo->ipo) execute_ipo((ID *)wo, wo->ipo);
1649                 wo= wo->id.next;
1650         }
1651
1652         la= G.main->lamp.first;
1653         while(la) {
1654                 if(la->ipo) execute_ipo((ID *)la, la->ipo);
1655                 la= la->id.next;
1656         }
1657
1658         ca= G.main->camera.first;
1659         while(ca) {
1660                 if(ca->ipo) execute_ipo((ID *)ca, ca->ipo);
1661                 ca= ca->id.next;
1662         }
1663
1664         snd= G.main->sound.first;
1665         while(snd) {
1666                 if(snd->ipo) execute_ipo((ID *)snd, snd->ipo);
1667                 snd= snd->id.next;
1668         }
1669
1670         /*just in case of...  WATCH IT: 2x */
1671         base= G.scene->base.first;
1672         while(base) {
1673                 
1674                 /* only update layer when an ipo */
1675                 if( has_ipo_code(base->object->ipo, OB_LAY) ) {
1676                         base->lay= base->object->lay;
1677                 }
1678                 
1679                 base= base->next;
1680         }
1681         
1682         /* just in case...*/
1683         if(G.scene->set) {
1684                 base= G.scene->set->base.first;
1685                 while(base) {
1686                         
1687                         /* only update layer when an ipo */
1688                         if( has_ipo_code(base->object->ipo, OB_LAY) ) {
1689                                 base->lay= base->object->lay;
1690                         }
1691                         
1692                         base= base->next;
1693                 }
1694         }
1695
1696         /* intrr: process FAC Ipos used as volume envelopes */
1697         ed= G.scene->ed;
1698         if (ed) {
1699                 seq= ed->seqbasep->first;
1700                 while(seq) {
1701                         if ((seq->type == SEQ_SOUND) && (seq->ipo)
1702                           &&(seq->startdisp<=G.scene->r.cfra+2) && (seq->enddisp>G.scene->r.cfra)) do_seq_ipo(seq);
1703                         seq= seq->next;
1704                 }
1705         }
1706
1707 }
1708
1709
1710 int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime)
1711 {
1712         IpoCurve *icu;
1713
1714         if(ipo==0) return 0;
1715
1716         icu= ipo->curve.first;
1717         while(icu) {
1718                 if(icu->adrcode == adrcode) {
1719                         if(icu->flag & IPO_LOCK);
1720                         else calc_icu(icu, *ctime);
1721                         
1722                         *ctime= icu->curval;
1723                         return 1;
1724                 }
1725                 icu= icu->next;
1726         }
1727         
1728         return 0;
1729 }
1730
1731
1732 /* ************************** */
1733
1734 void clear_delta_obipo(Ipo *ipo)
1735 {
1736         Object *ob;
1737         
1738         if(ipo==0) return;
1739         
1740         ob= G.main->object.first;
1741         while(ob) {
1742                 if(ob->id.lib==0) {
1743                         if(ob->ipo==ipo) {
1744                                 memset(&ob->dloc, 0, 12);
1745                                 memset(&ob->drot, 0, 12);
1746                                 memset(&ob->dsize, 0, 12);
1747                         }
1748                 }
1749                 ob= ob->id.next;
1750         }
1751 }
1752
1753 void add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
1754 {
1755         CfraElem *ce, *cen;
1756         
1757         ce= lb->first;
1758         while(ce) {
1759                 
1760                 if( ce->cfra==bezt->vec[1][0] ) {
1761                         /* do because of double keys */
1762                         if(bezt->f2 & 1) ce->sel= bezt->f2;
1763                         return;
1764                 }
1765                 else if(ce->cfra > bezt->vec[1][0]) break;
1766                 
1767                 ce= ce->next;
1768         }       
1769         
1770         cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); 
1771         if(ce) BLI_insertlinkbefore(lb, ce, cen);
1772         else BLI_addtail(lb, cen);
1773
1774         cen->cfra= bezt->vec[1][0];
1775         cen->sel= bezt->f2;
1776 }
1777
1778
1779
1780 void make_cfra_list(Ipo *ipo, ListBase *elems)
1781 {
1782         IpoCurve *icu;
1783         CfraElem *ce;
1784         BezTriple *bezt;
1785         int a;
1786         
1787         if(ipo->blocktype==ID_OB) {
1788                 icu= ipo->curve.first;
1789                 while(icu) {
1790                         if(icu->flag & IPO_VISIBLE) {
1791                                 switch(icu->adrcode) {
1792                                 case OB_DLOC_X:
1793                                 case OB_DLOC_Y:
1794                                 case OB_DLOC_Z:
1795                                 case OB_DROT_X:
1796                                 case OB_DROT_Y:
1797                                 case OB_DROT_Z:
1798                                 case OB_DSIZE_X:
1799                                 case OB_DSIZE_Y:
1800                                 case OB_DSIZE_Z:
1801
1802                                 case OB_LOC_X:
1803                                 case OB_LOC_Y:
1804                                 case OB_LOC_Z:
1805                                 case OB_ROT_X:
1806                                 case OB_ROT_Y:
1807                                 case OB_ROT_Z:
1808                                 case OB_SIZE_X:
1809                                 case OB_SIZE_Y:
1810                                 case OB_SIZE_Z:
1811                                         bezt= icu->bezt;
1812                                         if(bezt) {
1813                                                 a= icu->totvert;
1814                                                 while(a--) {
1815                                                         add_to_cfra_elem(elems, bezt);
1816                                                         bezt++;
1817                                                 }
1818                                         }
1819                                         break;
1820                                 }
1821                         }
1822                         icu= icu->next;
1823                 }
1824         }
1825         if(ipo->showkey==0) {
1826                 /* deselect all keys */
1827                 ce= elems->first;
1828                 while(ce) {
1829                         ce->sel= 0;
1830                         ce= ce->next;
1831                 }
1832         }
1833 }
1834
1835 /* *********************** INTERFACE FOR KETSJI ********** */
1836
1837
1838 int IPO_GetChannels(Ipo *ipo, IPO_Channel *channels)
1839 {
1840         /* channels is max 32 items, allocated by calling function */   
1841
1842         IpoCurve *icu;
1843         int total=0;
1844         
1845         if(ipo==NULL) return 0;
1846         
1847         icu= ipo->curve.first;
1848         while(icu) {
1849                 
1850                 channels[total]= icu->adrcode;
1851                 total++;
1852                 if(total>31) break;
1853                 
1854                 icu= icu->next;
1855         }
1856         
1857         return total;
1858 }
1859
1860
1861
1862 /* Get the float value for channel 'channel' at time 'ctime' */
1863
1864 float IPO_GetFloatValue(Ipo *ipo, IPO_Channel channel, float ctime)
1865 {
1866         if(ipo==NULL) return 0;
1867         
1868         calc_ipo_spec(ipo, channel, &ctime);
1869         
1870         if (OB_ROT_X <= channel && channel <= OB_DROT_Z) {
1871                 ctime *= (float)(M_PI_2/9.0); 
1872         }
1873
1874         return ctime;
1875 }
1876
1877
1878 void test_ipo_get()
1879 {
1880         Object *ob;
1881         int tot;
1882         IPO_Channel chan[32];
1883
1884         ob = (G.scene->basact ? G.scene->basact->object : 0);
1885         
1886         if(ob==NULL) return;
1887         if(ob->ipo==NULL) return;
1888         
1889         tot= IPO_GetChannels(ob->ipo, chan);
1890         printf("tot %d \n", tot);
1891         
1892         while(tot--) {
1893                 printf("var1 %d \n", chan[tot]);
1894         }
1895         
1896         printf("var1 %f \n", IPO_GetFloatValue(ob->ipo, chan[0], 10.0));
1897 }