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