reverting revision 16784 that broke compilation. Aligorith, please fix and recommit
[blender.git] / source / blender / blenkernel / intern / ipo.c
1 /* ipo.c
2  * 
3  * $Id$
4  *
5  * ***** BEGIN GPL 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.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 #include <math.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_action_types.h"
42 #include "DNA_armature_types.h"
43 #include "DNA_curve_types.h"
44 #include "DNA_camera_types.h"
45 #include "DNA_lamp_types.h"
46 #include "DNA_ipo_types.h"
47 #include "DNA_key_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_object_force.h"
52 #include "DNA_particle_types.h"
53 #include "DNA_sequence_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_sound_types.h"
56 #include "DNA_texture_types.h"
57 #include "DNA_view3d_types.h"
58 #include "DNA_world_types.h"
59
60 #include "BLI_blenlib.h"
61 #include "BLI_arithb.h"
62
63 #include "BKE_bad_level_calls.h"
64 #include "BKE_utildefines.h"
65
66 #include "BKE_action.h"
67 #include "BKE_blender.h"
68 #include "BKE_curve.h"
69 #include "BKE_constraint.h"
70 #include "BKE_global.h"
71 #include "BKE_ipo.h"
72 #include "BKE_library.h"
73 #include "BKE_main.h"
74 #include "BKE_mesh.h"
75 #include "BKE_object.h"
76 #include "BPY_extern.h" /* for BPY_pydriver_eval() */
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, CO_HEADTAIL
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_COL_R, OB_COL_G, OB_COL_B, OB_COL_A,
94         OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM, OB_PD_FMAXD
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_IOR, 
109         MA_MODE, MA_HASIZE, MA_TRANSLU, MA_RAYM,
110         MA_FRESMIR, MA_FRESMIRI, MA_FRESTRA, MA_FRESTRAI, MA_ADD,
111         
112         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
113         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
114         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
115         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF, MA_MAP1+MAP_DISP
116 };
117
118 int te_ar[TE_TOTIPO] ={
119         
120         TE_NSIZE, TE_NDEPTH, TE_NTYPE, TE_TURB,
121         
122         TE_VNW1, TE_VNW2, TE_VNW3, TE_VNW4,
123         TE_VNMEXP, TE_VN_COLT, TE_VN_DISTM,
124         
125         TE_ISCA, TE_DISTA,
126         
127         TE_MG_TYP, TE_MGH, TE_MG_LAC, TE_MG_OCT, TE_MG_OFF, TE_MG_GAIN,
128         
129         TE_N_BAS1, TE_N_BAS2,
130         
131         TE_COL_R, TE_COL_G, TE_COL_B, TE_BRIGHT, TE_CONTRA
132 };
133
134 int seq_ar[SEQ_TOTIPO]= {
135         SEQ_FAC1
136 };
137
138 int cu_ar[CU_TOTIPO]= {
139         CU_SPEED
140 };
141
142 int wo_ar[WO_TOTIPO]= {
143         WO_HOR_R, WO_HOR_G, WO_HOR_B, WO_ZEN_R, WO_ZEN_G, WO_ZEN_B, 
144         WO_EXPOS, WO_MISI, WO_MISTDI, WO_MISTSTA, WO_MISTHI,
145         WO_STAR_R, WO_STAR_G, WO_STAR_B, WO_STARDIST, WO_STARSIZE, 
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 la_ar[LA_TOTIPO]= {
154         LA_ENERGY,  LA_COL_R, LA_COL_G,  LA_COL_B, 
155         LA_DIST, LA_SPOTSI, LA_SPOTBL, 
156         LA_QUAD1,  LA_QUAD2,  LA_HALOINT,  
157
158         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
159         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
160         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
161         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF
162 };
163
164 /* yafray: aperture & focal distance curves added */
165 /* qdn: FDIST now available to Blender as well for defocus node */
166 int cam_ar[CAM_TOTIPO]= {
167         CAM_LENS, CAM_STA, CAM_END, CAM_YF_APERT, CAM_YF_FDIST, CAM_SHIFT_X, CAM_SHIFT_Y
168 };
169
170 int snd_ar[SND_TOTIPO]= {
171         SND_VOLUME, SND_PITCH, SND_PANNING, SND_ATTEN
172 };
173
174 int fluidsim_ar[FLUIDSIM_TOTIPO]= {
175         FLUIDSIM_VISC, FLUIDSIM_TIME,
176         FLUIDSIM_GRAV_X , FLUIDSIM_GRAV_Y , FLUIDSIM_GRAV_Z ,
177         FLUIDSIM_VEL_X  , FLUIDSIM_VEL_Y  , FLUIDSIM_VEL_Z  ,
178         FLUIDSIM_ACTIVE,
179         FLUIDSIM_ATTR_FORCE_STR, FLUIDSIM_ATTR_FORCE_RADIUS,
180         FLUIDSIM_VEL_FORCE_STR, FLUIDSIM_VEL_FORCE_RADIUS,
181 };
182
183 int part_ar[PART_TOTIPO]= {
184         PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, PART_EMIT_SIZE,
185         PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, PART_CLUMP,
186     PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, PART_KINK_SHAPE,
187         PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD, PART_PD2_FSTR, PART_PD2_FFALL, PART_PD2_FMAXD
188 };
189
190
191 float frame_to_float(int cfra)          /* see also bsystem_time in object.c */
192 {
193         extern float bluroffs;  /* bad stuff borrowed from object.c */
194         extern float fieldoffs;
195         float ctime;
196         
197         ctime= (float)cfra;
198         ctime+= bluroffs+fieldoffs;
199         ctime*= G.scene->r.framelen;
200         
201         return ctime;
202 }
203
204 /* includes ipo curve itself */
205 void free_ipo_curve(IpoCurve *icu) 
206 {
207         if(icu->bezt) MEM_freeN(icu->bezt);
208         if(icu->bp) MEM_freeN(icu->bp);
209         if(icu->driver) MEM_freeN(icu->driver);
210         MEM_freeN(icu);
211 }
212
213 /* do not free ipo itself */
214 void free_ipo(Ipo *ipo)
215 {
216         IpoCurve *icu;
217         
218         while( (icu= ipo->curve.first) ) {
219                 BLI_remlink(&ipo->curve, icu);
220                 free_ipo_curve(icu);
221         }
222 }
223
224 /* on adding new ipos, or for empty views */
225 void ipo_default_v2d_cur(int blocktype, rctf *cur)
226 {
227         if(blocktype==ID_CA) {
228                 cur->xmin= G.scene->r.sfra;
229                 cur->xmax= G.scene->r.efra;
230                 cur->ymin= 0.0;
231                 cur->ymax= 100.0;
232         }
233         else if ELEM5(blocktype, ID_MA, ID_CU, ID_WO, ID_LA, ID_CO) {
234                 cur->xmin= (float)G.scene->r.sfra-0.1;
235                 cur->xmax= G.scene->r.efra;
236                 cur->ymin= (float)-0.1;
237                 cur->ymax= (float)+1.1;
238         }
239         else if(blocktype==ID_TE) {
240                 cur->xmin= (float)G.scene->r.sfra-0.1;
241                 cur->xmax= G.scene->r.efra;
242                 cur->ymin= (float)-0.1;
243                 cur->ymax= (float)+1.1;
244         }
245         else if(blocktype==ID_SEQ) {
246                 cur->xmin= -5.0;
247                 cur->xmax= 105.0;
248                 cur->ymin= (float)-0.1;
249                 cur->ymax= (float)+1.1;
250         }
251         else if(blocktype==ID_KE) {
252                 cur->xmin= (float)G.scene->r.sfra-0.1;
253                 cur->xmax= G.scene->r.efra;
254                 cur->ymin= (float)-0.1;
255                 cur->ymax= (float)+2.1;
256         }
257         else {  /* ID_OB and everything else */
258                 cur->xmin= G.scene->r.sfra;
259                 cur->xmax= G.scene->r.efra;
260                 cur->ymin= -5.0;
261                 cur->ymax= +5.0;
262         }
263 }
264
265
266 Ipo *add_ipo(char *name, int idcode)
267 {
268         Ipo *ipo;
269         
270         ipo= alloc_libblock(&G.main->ipo, ID_IP, name);
271         ipo->blocktype= idcode;
272         ipo_default_v2d_cur(idcode, &ipo->cur);
273
274         return ipo;
275 }
276
277 Ipo *copy_ipo(Ipo *ipo)
278 {
279         Ipo *ipon;
280         IpoCurve *icu;
281         
282         if(ipo==NULL) return 0;
283         
284         ipon= copy_libblock(ipo);
285         
286         duplicatelist(&(ipon->curve), &(ipo->curve));
287
288         for(icu= ipo->curve.first; icu; icu= icu->next) {
289                 icu->bezt= MEM_dupallocN(icu->bezt);
290                 if(icu->driver) icu->driver= MEM_dupallocN(icu->driver);
291         }
292         
293         return ipon;
294 }
295
296 /* uses id->newid to match pointers with other copied data */
297 void ipo_idnew(Ipo *ipo)
298 {
299         if(ipo) {
300                 IpoCurve *icu;
301                 
302                 for(icu= ipo->curve.first; icu; icu= icu->next) {
303                         if(icu->driver) {
304                                 ID_NEW(icu->driver->ob);
305                         }
306                 }
307         }
308 }
309
310 void make_local_obipo(Ipo *ipo)
311 {
312         Object *ob;
313         Ipo *ipon;
314         int local=0, lib=0;
315         
316         /* - only lib users: do nothing
317          * - only local users: set flag
318          * - mixed: make copy
319          */
320
321         ob= G.main->object.first;
322         while(ob) {
323                 if(ob->ipo==ipo) {
324                         if(ob->id.lib) lib= 1;
325                         else local= 1;
326                 }
327                 ob= ob->id.next;
328         }
329         
330         if(local && lib==0) {
331                 ipo->id.lib= 0;
332                 ipo->id.flag= LIB_LOCAL;
333                 new_id(0, (ID *)ipo, 0);
334         }
335         else if(local && lib) {
336                 ipon= copy_ipo(ipo);
337                 ipon->id.us= 0;
338                 
339                 ob= G.main->object.first;
340                 while(ob) {
341                         if(ob->ipo==ipo) {
342                                 
343                                 if(ob->id.lib==NULL) {
344                                         ob->ipo= ipon;
345                                         ipon->id.us++;
346                                         ipo->id.us--;
347                                 }
348                         }
349                         ob= ob->id.next;
350                 }
351         }
352 }
353
354 void make_local_matipo(Ipo *ipo)
355 {
356         Material *ma;
357         Ipo *ipon;
358         int local=0, lib=0;
359
360         /* - only lib users: do nothing
361             * - only local users: set flag
362             * - mixed: make copy
363         */
364         
365         ma= G.main->mat.first;
366         while(ma) {
367                 if(ma->ipo==ipo) {
368                         if(ma->id.lib) lib= 1;
369                         else local= 1;
370                 }
371                 ma= ma->id.next;
372         }
373         
374         if(local && lib==0) {
375                 ipo->id.lib= 0;
376                 ipo->id.flag= LIB_LOCAL;
377                 new_id(0, (ID *)ipo, 0);
378         }
379         else if(local && lib) {
380                 ipon= copy_ipo(ipo);
381                 ipon->id.us= 0;
382                 
383                 ma= G.main->mat.first;
384                 while(ma) {
385                         if(ma->ipo==ipo) {
386                                 
387                                 if(ma->id.lib==NULL) {
388                                         ma->ipo= ipon;
389                                         ipon->id.us++;
390                                         ipo->id.us--;
391                                 }
392                         }
393                         ma= ma->id.next;
394                 }
395         }
396 }
397
398 void make_local_keyipo(Ipo *ipo)
399 {
400         Key *key;
401         Ipo *ipon;
402         int local=0, lib=0;
403
404         /* - only lib users: do nothing
405          * - only local users: set flag
406          * - mixed: make copy
407          */
408         
409         key= G.main->key.first;
410         while(key) {
411                 if(key->ipo==ipo) {
412                         if(key->id.lib) lib= 1;
413                         else local= 1;
414                 }
415                 key= key->id.next;
416         }
417         
418         if(local && lib==0) {
419                 ipo->id.lib= 0;
420                 ipo->id.flag= LIB_LOCAL;
421                 new_id(0, (ID *)ipo, 0);
422         }
423         else if(local && lib) {
424                 ipon= copy_ipo(ipo);
425                 ipon->id.us= 0;
426                 
427                 key= G.main->key.first;
428                 while(key) {
429                         if(key->ipo==ipo) {
430                                 
431                                 if(key->id.lib==NULL) {
432                                         key->ipo= ipon;
433                                         ipon->id.us++;
434                                         ipo->id.us--;
435                                 }
436                         }
437                         key= key->id.next;
438                 }
439         }
440 }
441
442
443 void make_local_ipo(Ipo *ipo)
444 {
445         
446         if(ipo->id.lib==NULL) return;
447         if(ipo->id.us==1) {
448                 ipo->id.lib= 0;
449                 ipo->id.flag= LIB_LOCAL;
450                 new_id(0, (ID *)ipo, 0);
451                 return;
452         }
453         
454         if(ipo->blocktype==ID_OB) make_local_obipo(ipo);
455         else if(ipo->blocktype==ID_MA) make_local_matipo(ipo);
456         else if(ipo->blocktype==ID_KE) make_local_keyipo(ipo);
457
458 }
459
460 IpoCurve *find_ipocurve(Ipo *ipo, int adrcode)
461 {
462         if(ipo) {
463                 IpoCurve *icu;
464                 for(icu= ipo->curve.first; icu; icu= icu->next) {
465                         if(icu->adrcode==adrcode) return icu;
466                 }
467         }
468         return NULL;
469 }
470
471 void calchandles_ipocurve(IpoCurve *icu)
472 {
473         BezTriple *bezt, *prev, *next;
474         int a;
475
476         a= icu->totvert;
477
478         /* IPO_CONST doesn't have handles */
479         if(a<2 || icu->ipo==IPO_CONST || icu->ipo==IPO_LIN) return;
480         
481         bezt= icu->bezt;
482         prev= 0;
483         next= bezt+1;
484
485         while(a--) {
486
487                 if(bezt->vec[0][0]>bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
488                 if(bezt->vec[2][0]<bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
489
490                 if(icu->flag & IPO_AUTO_HORIZ) 
491                         calchandleNurb(bezt, prev, next, 2);    /* 2==special autohandle && keep extrema horizontal */
492                 else
493                         calchandleNurb(bezt, prev, next, 1);    /* 1==special autohandle */
494         
495                 prev= bezt;
496                 if(a==1) {
497                         next= 0;
498                 }
499                 else next++;
500                         
501                 /* for automatic ease in and out */
502                 if(bezt->h1==HD_AUTO && bezt->h2==HD_AUTO) {
503                         if(a==0 || a==icu->totvert-1) {
504                                 if(icu->extrap==IPO_HORIZ) {
505                                         bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
506                                 }
507                         }
508                 }
509                 
510                 bezt++;
511         }
512 }
513
514 void testhandles_ipocurve(IpoCurve *icu)
515 {
516     /* use when something has changed with handles.
517     it treats all BezTriples with the following rules:
518     PHASE 1: do types have to be altered?
519      Auto handles: become aligned when selection status is NOT(000 || 111)
520      Vector handles: become 'nothing' when (one half selected AND other not)
521     PHASE 2: recalculate handles
522     */
523     BezTriple *bezt;
524         int flag, a;
525
526         bezt= icu->bezt;
527         if(bezt==NULL) return;
528         
529         a= icu->totvert;
530         while(a--) {
531                 flag= 0;
532                 if(bezt->f1 & SELECT) flag++;
533                 if(bezt->f2 & SELECT) flag += 2;
534                 if(bezt->f3 & SELECT) flag += 4;
535
536                 if( !(flag==0 || flag==7) ) {
537                         if(bezt->h1==HD_AUTO) {   /* auto */
538                                 bezt->h1= HD_ALIGN;
539                         }
540                         if(bezt->h2==HD_AUTO) {   /* auto */
541                                 bezt->h2= HD_ALIGN;
542                         }
543
544                         if(bezt->h1==HD_VECT) {   /* vector */
545                                 if(flag < 4) bezt->h1= 0;
546                         }
547                         if(bezt->h2==HD_VECT) {   /* vector */
548                                 if( flag > 3) bezt->h2= 0;
549                         }
550                 }
551                 bezt++;
552         }
553
554         calchandles_ipocurve(icu);
555 }
556
557
558 void sort_time_ipocurve(IpoCurve *icu)
559 {
560         BezTriple *bezt;
561         int a, ok= 1;
562         
563         while(ok) {
564                 ok= 0;
565
566                 if(icu->bezt) {
567                         bezt= icu->bezt;
568                         a= icu->totvert;
569                         while(a--) {
570                                 if(a>0) {
571                                         if( bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
572                                                 SWAP(BezTriple, *bezt, *(bezt+1));
573                                                 ok= 1;
574                                         }
575                                 }
576                                 if(bezt->vec[0][0]>bezt->vec[1][0] && bezt->vec[2][0]<bezt->vec[1][0]) {
577                                         SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
578                                         SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
579                                 }
580                                 else {
581                                         if(bezt->vec[0][0]>bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
582                                         if(bezt->vec[2][0]<bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
583                                 }
584                                 bezt++;
585                         }
586                 }
587                 else {
588                         
589                 }
590         }
591 }
592
593 int test_time_ipocurve(IpoCurve *icu)
594 {
595         BezTriple *bezt;
596         int a;
597         
598         if(icu->bezt) {
599                 bezt= icu->bezt;
600                 a= icu->totvert-1;
601                 while(a--) {
602                         if( bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
603                                 return 1;
604                         }
605                         bezt++;
606                 }       
607         }
608         else {
609                 
610         }
611
612         return 0;
613 }
614
615 void correct_bezpart(float *v1, float *v2, float *v3, float *v4)
616 {
617         /* the total length of the handles is not allowed to be more
618          * than the horizontal distance between (v1-v4)
619          * this to prevent curve loops
620          */
621         float h1[2], h2[2], len1, len2, len, fac;
622         
623         h1[0]= v1[0]-v2[0];
624         h1[1]= v1[1]-v2[1];
625         h2[0]= v4[0]-v3[0];
626         h2[1]= v4[1]-v3[1];
627         
628         len= v4[0]- v1[0];
629         len1= (float)fabs(h1[0]);
630         len2= (float)fabs(h2[0]);
631         
632         if(len1+len2==0.0) return;
633         if(len1+len2 > len) {
634                 fac= len/(len1+len2);
635                 
636                 v2[0]= (v1[0]-fac*h1[0]);
637                 v2[1]= (v1[1]-fac*h1[1]);
638                 
639                 v3[0]= (v4[0]-fac*h2[0]);
640                 v3[1]= (v4[1]-fac*h2[1]);
641                 
642         }
643 }
644
645 /* *********************** ARITH *********************** */
646
647 int findzero(float x, float q0, float q1, float q2, float q3, float *o)
648 {
649         double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
650         int nr= 0;
651
652         c0= q0-x;
653         c1= 3*(q1-q0);
654         c2= 3*(q0-2*q1+q2);
655         c3= q3-q0+3*(q1-q2);
656         
657         if(c3!=0.0) {
658                 a= c2/c3;
659                 b= c1/c3;
660                 c= c0/c3;
661                 a= a/3;
662
663                 p= b/3-a*a;
664                 q= (2*a*a*a-a*b+c)/2;
665                 d= q*q+p*p*p;
666
667                 if(d>0.0) {
668                         t= sqrt(d);
669                         o[0]= (float)(Sqrt3d(-q+t)+Sqrt3d(-q-t)-a);
670                         if(o[0]>= SMALL && o[0]<=1.000001) return 1;
671                         else return 0;
672                 }
673                 else if(d==0.0) {
674                         t= Sqrt3d(-q);
675                         o[0]= (float)(2*t-a);
676                         if(o[0]>=SMALL && o[0]<=1.000001) nr++;
677                         o[nr]= (float)(-t-a);
678                         if(o[nr]>=SMALL && o[nr]<=1.000001) return nr+1;
679                         else return nr;
680                 }
681                 else {
682                         phi= acos(-q/sqrt(-(p*p*p)));
683                         t= sqrt(-p);
684                         p= cos(phi/3);
685                         q= sqrt(3-3*p*p);
686                         o[0]= (float)(2*t*p-a);
687                         if(o[0]>=SMALL && o[0]<=1.000001) nr++;
688                         o[nr]= (float)(-t*(p+q)-a);
689                         if(o[nr]>=SMALL && o[nr]<=1.000001) nr++;
690                         o[nr]= (float)(-t*(p-q)-a);
691                         if(o[nr]>=SMALL && o[nr]<=1.000001) return nr+1;
692                         else return nr;
693                 }
694         }
695         else {
696                 a=c2;
697                 b=c1;
698                 c=c0;
699                 
700                 if(a!=0.0) {
701                         p=b*b-4*a*c;
702                         if(p>0) {
703                                 p= sqrt(p);
704                                 o[0]= (float)((-b-p)/(2*a));
705                                 if(o[0]>=SMALL && o[0]<=1.000001) nr++;
706                                 o[nr]= (float)((-b+p)/(2*a));
707                                 if(o[nr]>=SMALL && o[nr]<=1.000001) return nr+1;
708                                 else return nr;
709                         }
710                         else if(p==0) {
711                                 o[0]= (float)(-b/(2*a));
712                                 if(o[0]>=SMALL && o[0]<=1.000001) return 1;
713                                 else return 0;
714                         }
715                 }
716                 else if(b!=0.0) {
717                         o[0]= (float)(-c/b);
718                         if(o[0]>=SMALL && o[0]<=1.000001) return 1;
719                         else return 0;
720                 }
721                 else if(c==0.0) {
722                         o[0]= 0.0;
723                         return 1;
724                 }
725                 return 0;       
726         }
727 }
728
729 void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
730 {
731         float t, c0, c1, c2, c3;
732         int a;
733
734         c0= f1;
735         c1= 3.0f*(f2 - f1);
736         c2= 3.0f*(f1 - 2.0f*f2 + f3);
737         c3= f4 - f1 + 3.0f*(f2-f3);
738         
739         for(a=0; a<b; a++) {
740                 t= o[a];
741                 o[a]= c0+t*c1+t*t*c2+t*t*t*c3;
742         }
743 }
744
745 void berekenx(float *f, float *o, int b)
746 {
747         float t, c0, c1, c2, c3;
748         int a;
749
750         c0= f[0];
751         c1= 3*(f[3]-f[0]);
752         c2= 3*(f[0]-2*f[3]+f[6]);
753         c3= f[9]-f[0]+3*(f[3]-f[6]);
754         for(a=0; a<b; a++) {
755                 t= o[a];
756                 o[a]= c0+t*c1+t*t*c2+t*t*t*c3;
757         }
758 }
759
760 /* we need the local transform = current transform - (parent transform + bone transform) */
761 /* (local transform is on action channel level) */
762 static void posechannel_get_local_transform(bPoseChannel *pchan, float *loc, float *eul, float *size)
763 {
764         float diff_mat[4][4];
765         float parmat[4][4], offs_bone[4][4], imat[4][4];
766         
767         if (pchan->parent) {
768                 /* get first the parent + bone transform in parmat */
769                 
770                 /* bone transform itself */
771                 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
772                 /* The bone's root offset (is in the parent's coordinate system) */
773                 VECCOPY(offs_bone[3], pchan->bone->head);
774                 /* Get the length translation of parent (length along y axis) */
775                 offs_bone[3][1]+= pchan->parent->bone->length;
776         
777                 Mat4MulSerie(parmat, pchan->parent->pose_mat, offs_bone, NULL, NULL, NULL, NULL, NULL, NULL);
778                 
779                 /* invert it */
780                 Mat4Invert(imat, parmat);
781         }
782         else {
783                 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
784                 VECCOPY(offs_bone[3], pchan->bone->head);
785
786                 /* invert it */
787                 Mat4Invert(imat, offs_bone);
788                 
789         }
790         
791         /* difference: current transform - (parent transform + bone transform)  */
792         Mat4MulMat4(diff_mat, pchan->pose_mat, imat);
793
794         if(loc)
795                 VECCOPY(loc, diff_mat[3]);
796         if(eul)
797                 Mat4ToEul(diff_mat, eul);
798         if(size)
799                 Mat4ToSize(diff_mat, size);
800         
801 }
802
803 /* has to return a float value */
804 static float eval_driver(IpoDriver *driver, float ipotime)
805 {
806         
807         if(driver->type == IPO_DRIVER_TYPE_PYTHON) {
808                 /* check for empty or invalid expression */
809                 if ((driver->name[0] == '\0') ||
810                         (driver->flag & IPO_DRIVER_FLAG_INVALID))
811                         return 0.0f;
812                 /* this evals the expression and returns its result:
813                  * (on errors it reports, then returns 0.0f) */
814                 return BPY_pydriver_eval(driver);
815         }
816         else {
817                 Object *ob= driver->ob;
818
819                 if(ob==NULL) return 0.0f;
820                 if(ob->proxy_from)
821                         ob= ob->proxy_from;
822                 
823                 if(driver->blocktype==ID_OB) {
824                         /* depsgraph failure; ob ipos are calculated in where_is_object, this might get called too late */
825                         if(ob->ipo && ob->ctime!=ipotime) {
826                                 calc_ipo_spec(ob->ipo, driver->adrcode, &ipotime);
827                                 return ipotime;
828                         }
829                         
830                         switch(driver->adrcode) {
831                         case OB_LOC_X:
832                                 return ob->loc[0];
833                         case OB_LOC_Y:
834                                 return ob->loc[1];
835                         case OB_LOC_Z:
836                                 return ob->loc[2];
837                         case OB_ROT_X:
838                                 return ob->rot[0]/(M_PI_2/9.0);
839                         case OB_ROT_Y:
840                                 return ob->rot[1]/(M_PI_2/9.0);
841                         case OB_ROT_Z:
842                                 return ob->rot[2]/(M_PI_2/9.0);
843                         case OB_SIZE_X:
844                                 return ob->size[0];
845                         case OB_SIZE_Y:
846                                 return ob->size[1];
847                         case OB_SIZE_Z:
848                                 return ob->size[2];
849                         }
850                 }
851                 else {  /* ID_AR */
852                         bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
853                         if(pchan && pchan->bone) {
854                                 
855                                 /* rotation difference is not a simple driver (i.e. value drives value), but the angle between 2 bones is driving stuff... which is useful */
856                                 if(driver->adrcode==OB_ROT_DIFF) {
857                                         bPoseChannel *pchan2= get_pose_channel(ob->pose, driver->name+DRIVER_NAME_OFFS);
858                                         if(pchan2 && pchan2->bone) {
859                                                 float q1[4], q2[4], quat[4], angle;
860                                                 
861                                                 Mat4ToQuat(pchan->pose_mat, q1);
862                                                 Mat4ToQuat(pchan2->pose_mat, q2);
863                                                 
864                                                 QuatInv(q1);
865                                                 QuatMul(quat, q1, q2);
866                                                 angle = 2.0f * (saacos(quat[0]));
867                                                 angle= ABS(angle);
868                                                 
869                                                 return angle>M_PI?2.0f*M_PI-angle:angle;
870                                         }
871                                 }
872                                 else {
873                                         float loc[3], eul[3], size[3];
874                                         
875                                         posechannel_get_local_transform(pchan, loc, eul, size);
876
877                                         switch(driver->adrcode) {
878                                         case OB_LOC_X:
879                                                 return loc[0];
880                                         case OB_LOC_Y:
881                                                 return loc[1];
882                                         case OB_LOC_Z:
883                                                 return loc[2];
884                                         case OB_ROT_X:
885                                                 return eul[0]/(M_PI_2/9.0);
886                                         case OB_ROT_Y:
887                                                 return eul[1]/(M_PI_2/9.0);
888                                         case OB_ROT_Z:
889                                                 return eul[2]/(M_PI_2/9.0);
890                                         case OB_SIZE_X:
891                                                 return size[0];
892                                         case OB_SIZE_Y:
893                                                 return size[1];
894                                         case OB_SIZE_Z:
895                                                 return size[2];
896                                         }
897                                 }
898                         }
899                 }
900         }       
901         return 0.0f;
902 }
903
904 float eval_icu(IpoCurve *icu, float ipotime) 
905 {
906         BezTriple *bezt, *prevbezt;
907         float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
908         float cycdx, cycdy, ofs, cycyofs, cvalue = 0.0;
909         int a, b;
910         
911         cycyofs= 0.0;
912         
913         if(icu->driver) {
914                 /* ipotime now serves as input for the curve */
915                 ipotime= cvalue= eval_driver(icu->driver, ipotime);
916         }
917         if(icu->bezt) {
918                 prevbezt= icu->bezt;
919                 bezt= prevbezt+1;
920                 a= icu->totvert-1;
921                 
922                 /* cyclic? */
923                 if(icu->extrap & IPO_CYCL) {
924                         ofs= icu->bezt->vec[1][0];
925                         cycdx= (icu->bezt+icu->totvert-1)->vec[1][0] - ofs;
926                         cycdy= (icu->bezt+icu->totvert-1)->vec[1][1] - icu->bezt->vec[1][1];
927                         if(cycdx!=0.0) {
928                                 
929                                 if(icu->extrap & IPO_DIR) {
930                                         cycyofs= (float)floor((ipotime-ofs)/cycdx);
931                                         cycyofs*= cycdy;
932                                 }
933
934                                 ipotime= (float)(fmod(ipotime-ofs, cycdx)+ofs);
935                                 if(ipotime<ofs) ipotime+= cycdx;
936                         }
937                 }
938                 
939                 /* endpoints? */
940         
941                 if(prevbezt->vec[1][0]>=ipotime) {
942                         if( (icu->extrap & IPO_DIR) && icu->ipo!=IPO_CONST) {
943                                 if (icu->ipo==IPO_LIN) {
944                                         if (icu->totvert==1) cvalue= prevbezt->vec[1][1];
945                                         else {
946                                                 /* use the next center point instead of our own handle for
947                                                  * linear interpolated extrapolate */
948                                                 bezt = prevbezt+1;
949                                                 dx= prevbezt->vec[1][0]-ipotime;
950                                                 fac= bezt->vec[1][0]-prevbezt->vec[1][0];
951                                                 if(fac!=0.0) {
952                                                         fac= (bezt->vec[1][1]-prevbezt->vec[1][1])/fac;
953                                                         cvalue= prevbezt->vec[1][1]-fac*dx;
954                                                 }
955                                                 else cvalue= prevbezt->vec[1][1];
956                                         }
957                                 } else {
958                                         dx= prevbezt->vec[1][0]-ipotime;
959                                         fac= prevbezt->vec[1][0]-prevbezt->vec[0][0];
960                                         if(fac!=0.0) {
961                                                 fac= (prevbezt->vec[1][1]-prevbezt->vec[0][1])/fac;
962                                                 cvalue= prevbezt->vec[1][1]-fac*dx;
963                                         }
964                                         else cvalue= prevbezt->vec[1][1];
965                                 }
966                         }
967                         else cvalue= prevbezt->vec[1][1];
968                         
969                         cvalue+= cycyofs;
970                 }
971                 else if( (prevbezt+a)->vec[1][0]<=ipotime) {
972                         if( (icu->extrap & IPO_DIR) && icu->ipo!=IPO_CONST) {
973                                 prevbezt+= a;
974                                 
975                                 if (icu->ipo==IPO_LIN) {
976                                         if (icu->totvert==1) cvalue= prevbezt->vec[1][1];
977                                         else {
978                                                 /* use the previous center point instead of our own handle for
979                                                  * linear interpolated extrapolate */
980                                                 bezt = prevbezt-1;
981                                                 dx= ipotime-prevbezt->vec[1][0];
982                                                 fac= prevbezt->vec[1][0]-bezt->vec[1][0];
983
984                                                 if(fac!=0) {
985                                                         fac= (prevbezt->vec[1][1]-bezt->vec[1][1])/fac;
986                                                         cvalue= prevbezt->vec[1][1]+fac*dx;
987                                                 }
988                                                 else cvalue= prevbezt->vec[1][1];
989                                         }
990                                 } else {
991                                         dx= ipotime-prevbezt->vec[1][0];
992                                         fac= prevbezt->vec[2][0]-prevbezt->vec[1][0];
993
994                                         if(fac!=0) {
995                                                 fac= (prevbezt->vec[2][1]-prevbezt->vec[1][1])/fac;
996                                                 cvalue= prevbezt->vec[1][1]+fac*dx;
997                                         }
998                                         else cvalue= prevbezt->vec[1][1];
999                                 }
1000                         }
1001                         else cvalue= (prevbezt+a)->vec[1][1];
1002                         
1003                         cvalue+= cycyofs;
1004                 }
1005                 else {
1006                         while(a--) {
1007                                 if(prevbezt->vec[1][0]<=ipotime && bezt->vec[1][0]>=ipotime) {
1008                                         if(icu->ipo==IPO_CONST) {
1009                                                 cvalue= prevbezt->vec[1][1]+cycyofs;
1010                                         }
1011                                         else if(icu->ipo==IPO_LIN) {
1012                                                 fac= bezt->vec[1][0]-prevbezt->vec[1][0];
1013                                                 if(fac==0) cvalue= cycyofs+prevbezt->vec[1][1];
1014                                                 else {
1015                                                         fac= (ipotime-prevbezt->vec[1][0])/fac;
1016                                                         cvalue= cycyofs+prevbezt->vec[1][1]+ fac*(bezt->vec[1][1]-prevbezt->vec[1][1]);
1017                                                 }
1018                                         }
1019                                         else {
1020                                                 v1[0]= prevbezt->vec[1][0];
1021                                                 v1[1]= prevbezt->vec[1][1];
1022                                                 v2[0]= prevbezt->vec[2][0];
1023                                                 v2[1]= prevbezt->vec[2][1];
1024                                                 
1025                                                 v3[0]= bezt->vec[0][0];
1026                                                 v3[1]= bezt->vec[0][1];
1027                                                 v4[0]= bezt->vec[1][0];
1028                                                 v4[1]= bezt->vec[1][1];
1029
1030                                                 correct_bezpart(v1, v2, v3, v4);
1031                                                 
1032                                                 b= findzero(ipotime, v1[0], v2[0], v3[0], v4[0], opl);
1033                                                 if(b) {
1034                                                         berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
1035                                                         cvalue= opl[0]+cycyofs;
1036                                                         break;
1037                                                 }
1038                                         }
1039                                 }
1040                                 prevbezt= bezt;
1041                                 bezt++;
1042                         }
1043                 }
1044         }
1045
1046         if(icu->ymin < icu->ymax) {
1047                 if(cvalue < icu->ymin) cvalue= icu->ymin;
1048                 else if(cvalue > icu->ymax) cvalue= icu->ymax;
1049         }
1050         
1051         return cvalue;
1052 }
1053
1054 void calc_icu(IpoCurve *icu, float ctime)
1055 {
1056         icu->curval= eval_icu(icu, ctime);
1057 }
1058
1059 float calc_ipo_time(Ipo *ipo, float ctime)
1060 {
1061
1062         if(ipo && ipo->blocktype==ID_OB) {
1063                 IpoCurve *icu= ipo->curve.first;
1064
1065                 while(icu) {
1066                         if (icu->adrcode==OB_TIME) {
1067                                 calc_icu(icu, ctime);
1068                                 return 10.0f*icu->curval;
1069                         }
1070                         icu= icu->next;
1071                 }       
1072         }
1073         
1074         return ctime;
1075 }
1076
1077 void calc_ipo(Ipo *ipo, float ctime)
1078 {
1079         IpoCurve *icu;
1080         
1081         if(ipo==NULL) return;
1082         if(ipo->muteipo) return;
1083         
1084         for(icu= ipo->curve.first; icu; icu= icu->next) {
1085                 if(icu->driver || (icu->flag & IPO_LOCK)==0) { 
1086                         if((icu->flag & IPO_MUTE)==0)
1087                                 calc_icu(icu, ctime);
1088                 }
1089         }
1090 }
1091
1092 /* ************************************** */
1093 /*              DO THE IPO!                                               */
1094 /* ************************************** */
1095
1096 void write_ipo_poin(void *poin, int type, float val)
1097 {
1098
1099         switch(type) {
1100         case IPO_FLOAT:
1101                 *( (float *)poin)= val;
1102                 break;
1103         case IPO_FLOAT_DEGR:
1104                 *( (float *)poin)= (float)(val*M_PI_2/9.0);
1105                 break;
1106         case IPO_INT:
1107         case IPO_INT_BIT:
1108         case IPO_LONG:
1109                 *( (int *)poin)= (int)val;
1110                 break;
1111         case IPO_SHORT:
1112         case IPO_SHORT_BIT:
1113                 *( (short *)poin)= (short)val;
1114                 break;
1115         case IPO_CHAR:
1116         case IPO_CHAR_BIT:
1117                 *( (char *)poin)= (char)val;
1118                 break;
1119         }
1120 }
1121
1122 float read_ipo_poin(void *poin, int type)
1123 {
1124         float val = 0.0;
1125         
1126         switch(type) {
1127         case IPO_FLOAT:
1128                 val= *( (float *)poin);
1129                 break;
1130         case IPO_FLOAT_DEGR:
1131                 val= *( (float *)poin);
1132                 val = (float)(val/(M_PI_2/9.0));
1133                 break;
1134         case IPO_INT:
1135         case IPO_INT_BIT:
1136         case IPO_LONG:
1137                 val= (float)(*( (int *)poin));
1138                 break;
1139         case IPO_SHORT:
1140         case IPO_SHORT_BIT:
1141                 val= *( (short *)poin);
1142                 break;
1143         case IPO_CHAR:
1144         case IPO_CHAR_BIT:
1145                 val= *( (char *)poin);
1146                 break;
1147         }
1148         return val;
1149 }
1150
1151 static void *give_tex_poin(Tex *tex, int adrcode, int *type )
1152 {
1153         void *poin=0;
1154
1155         switch(adrcode) {
1156         case TE_NSIZE:
1157                 poin= &(tex->noisesize); break;
1158         case TE_TURB:
1159                 poin= &(tex->turbul); break;
1160         case TE_NDEPTH:
1161                 poin= &(tex->noisedepth); *type= IPO_SHORT; break;
1162         case TE_NTYPE:
1163                 poin= &(tex->noisetype); *type= IPO_SHORT; break;
1164         case TE_VNW1:
1165                 poin= &(tex->vn_w1); break;
1166         case TE_VNW2:
1167                 poin= &(tex->vn_w2); break;
1168         case TE_VNW3:
1169                 poin= &(tex->vn_w3); break;
1170         case TE_VNW4:
1171                 poin= &(tex->vn_w4); break;
1172         case TE_VNMEXP:
1173                 poin= &(tex->vn_mexp); break;
1174         case TE_ISCA:
1175                 poin= &(tex->ns_outscale); break;
1176         case TE_DISTA:
1177                 poin= &(tex->dist_amount); break;
1178         case TE_VN_COLT:
1179                 poin= &(tex->vn_coltype); *type= IPO_SHORT; break;
1180         case TE_VN_DISTM:
1181                 poin= &(tex->vn_distm); *type= IPO_SHORT; break;
1182         case TE_MG_TYP:
1183                 poin= &(tex->stype); *type= IPO_SHORT; break;
1184         case TE_MGH:
1185                 poin= &(tex->mg_H); break;
1186         case TE_MG_LAC:
1187                 poin= &(tex->mg_lacunarity); break;
1188         case TE_MG_OCT:
1189                 poin= &(tex->mg_octaves); break;
1190         case TE_MG_OFF:
1191                 poin= &(tex->mg_offset); break;
1192         case TE_MG_GAIN:
1193                 poin= &(tex->mg_gain); break;
1194         case TE_N_BAS1:
1195                 poin= &(tex->noisebasis); *type= IPO_SHORT; break;
1196         case TE_N_BAS2:
1197                 poin= &(tex->noisebasis2); *type= IPO_SHORT; break;
1198         case TE_COL_R:
1199                 poin= &(tex->rfac); break;
1200         case TE_COL_G:
1201                 poin= &(tex->gfac); break;
1202         case TE_COL_B:
1203                 poin= &(tex->bfac); break;
1204         case TE_BRIGHT:
1205                 poin= &(tex->bright); break;
1206         case TE_CONTRA:
1207                 poin= &(tex->contrast); break;
1208
1209         }
1210         
1211         return poin;
1212 }
1213
1214 void *give_mtex_poin(MTex *mtex, int adrcode )
1215 {
1216         void *poin=0;
1217                 
1218         switch(adrcode) {
1219         case MAP_OFS_X:
1220                 poin= &(mtex->ofs[0]); break;
1221         case MAP_OFS_Y:
1222                 poin= &(mtex->ofs[1]); break;
1223         case MAP_OFS_Z:
1224                 poin= &(mtex->ofs[2]); break;
1225         case MAP_SIZE_X:
1226                 poin= &(mtex->size[0]); break;
1227         case MAP_SIZE_Y:
1228                 poin= &(mtex->size[1]); break;
1229         case MAP_SIZE_Z:
1230                 poin= &(mtex->size[2]); break;
1231         case MAP_R:
1232                 poin= &(mtex->r); break;
1233         case MAP_G:
1234                 poin= &(mtex->g); break;
1235         case MAP_B:
1236                 poin= &(mtex->b); break;
1237         case MAP_DVAR:
1238                 poin= &(mtex->def_var); break;
1239         case MAP_COLF:
1240                 poin= &(mtex->colfac); break;
1241         case MAP_NORF:
1242                 poin= &(mtex->norfac); break;
1243         case MAP_VARF:
1244                 poin= &(mtex->varfac); break;
1245         case MAP_DISP:
1246                 poin= &(mtex->dispfac); break;
1247         }
1248         
1249         return poin;
1250 }
1251
1252 /* GS reads the memory pointed at in a specific ordering. There are,
1253  * however two definitions for it. I have jotted them down here, both,
1254  * but I think the first one is actually used. The thing is that
1255  * big-endian systems might read this the wrong way round. OTOH, we
1256  * constructed the IDs that are read out with this macro explicitly as
1257  * well. I expect we'll sort it out soon... */
1258
1259 /* from blendef: */
1260 #define GS(a)   (*((short *)(a)))
1261
1262 /* from misc_util: flip the bytes from x  */
1263 /*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
1264
1265 void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
1266 {
1267         void *poin= NULL;
1268         Object *ob;
1269         Material *ma;
1270         MTex *mtex;
1271         Tex *tex;
1272         Lamp *la;
1273         Sequence *seq;
1274         World *wo;
1275         ParticleSettings *part;
1276
1277         *type= IPO_FLOAT;
1278
1279         if( GS(id->name)==ID_OB) {
1280                 
1281                 ob= (Object *)id;
1282
1283                 switch(icu->adrcode) {
1284                 case OB_LOC_X:
1285                         poin= &(ob->loc[0]); break;
1286                 case OB_LOC_Y:
1287                         poin= &(ob->loc[1]); break;
1288                 case OB_LOC_Z:
1289                         poin= &(ob->loc[2]); break;
1290                 case OB_DLOC_X:
1291                         poin= &(ob->dloc[0]); break;
1292                 case OB_DLOC_Y:
1293                         poin= &(ob->dloc[1]); break;
1294                 case OB_DLOC_Z:
1295                         poin= &(ob->dloc[2]); break;
1296         
1297                 case OB_ROT_X:
1298                         poin= &(ob->rot[0]); *type= IPO_FLOAT_DEGR; break;
1299                 case OB_ROT_Y:
1300                         poin= &(ob->rot[1]); *type= IPO_FLOAT_DEGR; break;
1301                 case OB_ROT_Z:
1302                         poin= &(ob->rot[2]); *type= IPO_FLOAT_DEGR; break;
1303                 case OB_DROT_X:
1304                         poin= &(ob->drot[0]); *type= IPO_FLOAT_DEGR; break;
1305                 case OB_DROT_Y:
1306                         poin= &(ob->drot[1]); *type= IPO_FLOAT_DEGR; break;
1307                 case OB_DROT_Z:
1308                         poin= &(ob->drot[2]); *type= IPO_FLOAT_DEGR; break;
1309                         
1310                 case OB_SIZE_X:
1311                         poin= &(ob->size[0]); break;
1312                 case OB_SIZE_Y:
1313                         poin= &(ob->size[1]); break;
1314                 case OB_SIZE_Z:
1315                         poin= &(ob->size[2]); break;
1316                 case OB_DSIZE_X:
1317                         poin= &(ob->dsize[0]); break;
1318                 case OB_DSIZE_Y:
1319                         poin= &(ob->dsize[1]); break;
1320                 case OB_DSIZE_Z:
1321                         poin= &(ob->dsize[2]); break;
1322
1323                 case OB_LAY:
1324                         poin= &(ob->lay); *type= IPO_INT_BIT; break;
1325                         
1326                 case OB_COL_R:  
1327                         poin= &(ob->col[0]);
1328                         break;
1329                 case OB_COL_G:
1330                         poin= &(ob->col[1]);
1331                         break;
1332                 case OB_COL_B:
1333                         poin= &(ob->col[2]);
1334                         break;
1335                 case OB_COL_A:
1336                         poin= &(ob->col[3]);
1337                         break;
1338                 case OB_PD_FSTR:
1339                         if(ob->pd) poin= &(ob->pd->f_strength);
1340                         break;
1341                 case OB_PD_FFALL:
1342                         if(ob->pd) poin= &(ob->pd->f_power);
1343                         break;
1344                 case OB_PD_SDAMP:
1345                         if(ob->pd) poin= &(ob->pd->pdef_damp);
1346                         break;
1347                 case OB_PD_RDAMP:
1348                         if(ob->pd) poin= &(ob->pd->pdef_rdamp);
1349                         break;
1350                 case OB_PD_PERM:
1351                         if(ob->pd) poin= &(ob->pd->pdef_perm);
1352                         break;
1353                 case OB_PD_FMAXD:
1354                         if(ob->pd) poin= &(ob->pd->maxdist);
1355                         break;
1356                 }
1357         }
1358         else if( GS(id->name)==ID_MA) {
1359                 
1360                 ma= (Material *)id;
1361                 
1362                 switch(icu->adrcode) {
1363                 case MA_COL_R:
1364                         poin= &(ma->r); break;
1365                 case MA_COL_G:
1366                         poin= &(ma->g); break;
1367                 case MA_COL_B:
1368                         poin= &(ma->b); break;
1369                 case MA_SPEC_R:
1370                         poin= &(ma->specr); break;
1371                 case MA_SPEC_G:
1372                         poin= &(ma->specg); break;
1373                 case MA_SPEC_B:
1374                         poin= &(ma->specb); break;
1375                 case MA_MIR_R:
1376                         poin= &(ma->mirr); break;
1377                 case MA_MIR_G:
1378                         poin= &(ma->mirg); break;
1379                 case MA_MIR_B:
1380                         poin= &(ma->mirb); break;
1381                 case MA_REF:
1382                         poin= &(ma->ref); break;
1383                 case MA_ALPHA:
1384                         poin= &(ma->alpha); break;
1385                 case MA_EMIT:
1386                         poin= &(ma->emit); break;
1387                 case MA_AMB:
1388                         poin= &(ma->amb); break;
1389                 case MA_SPEC:
1390                         poin= &(ma->spec); break;
1391                 case MA_HARD:
1392                         poin= &(ma->har); *type= IPO_SHORT; break;
1393                 case MA_SPTR:
1394                         poin= &(ma->spectra); break;
1395                 case MA_IOR:
1396                         poin= &(ma->ang); break;
1397                 case MA_MODE:
1398                         poin= &(ma->mode); *type= IPO_INT_BIT; break;
1399                 case MA_HASIZE:
1400                         poin= &(ma->hasize); break;
1401                 case MA_TRANSLU:
1402                         poin= &(ma->translucency); break;
1403                 case MA_RAYM:
1404                         poin= &(ma->ray_mirror); break;
1405                 case MA_FRESMIR:
1406                         poin= &(ma->fresnel_mir); break;
1407                 case MA_FRESMIRI:
1408                         poin= &(ma->fresnel_mir_i); break;
1409                 case MA_FRESTRA:
1410                         poin= &(ma->fresnel_tra); break;
1411                 case MA_FRESTRAI:
1412                         poin= &(ma->fresnel_tra_i); break;
1413                 case MA_ADD:
1414                         poin= &(ma->add); break;
1415                 }
1416                 
1417                 if(poin==NULL) {
1418                         mtex= 0;
1419                         if(icu->adrcode & MA_MAP1) mtex= ma->mtex[0];
1420                         else if(icu->adrcode & MA_MAP2) mtex= ma->mtex[1];
1421                         else if(icu->adrcode & MA_MAP3) mtex= ma->mtex[2];
1422                         else if(icu->adrcode & MA_MAP4) mtex= ma->mtex[3];
1423                         else if(icu->adrcode & MA_MAP5) mtex= ma->mtex[4];
1424                         else if(icu->adrcode & MA_MAP6) mtex= ma->mtex[5];
1425                         else if(icu->adrcode & MA_MAP7) mtex= ma->mtex[6];
1426                         else if(icu->adrcode & MA_MAP8) mtex= ma->mtex[7];
1427                         else if(icu->adrcode & MA_MAP9) mtex= ma->mtex[8];
1428                         else if(icu->adrcode & MA_MAP10) mtex= ma->mtex[9];
1429                         else if(icu->adrcode & MA_MAP12) mtex= ma->mtex[11];
1430                         else if(icu->adrcode & MA_MAP11) mtex= ma->mtex[10];
1431                         else if(icu->adrcode & MA_MAP13) mtex= ma->mtex[12];
1432                         else if(icu->adrcode & MA_MAP14) mtex= ma->mtex[13];
1433                         else if(icu->adrcode & MA_MAP15) mtex= ma->mtex[14];
1434                         else if(icu->adrcode & MA_MAP16) mtex= ma->mtex[15];
1435                         else if(icu->adrcode & MA_MAP17) mtex= ma->mtex[16];
1436                         else if(icu->adrcode & MA_MAP18) mtex= ma->mtex[17];
1437                         
1438                         if(mtex) {
1439                                 poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
1440                         }
1441                 }
1442         }
1443         else if( GS(id->name)==ID_TE) {
1444                 tex= (Tex *)id;
1445                 
1446                 if(tex) poin= give_tex_poin(tex, icu->adrcode, type);
1447         }
1448         else if( GS(id->name)==ID_SEQ) {
1449                 seq= (Sequence *)id;
1450                 
1451                 switch(icu->adrcode) {
1452                 case SEQ_FAC1:
1453                         poin= &(seq->facf0); break;
1454                 }
1455         }
1456         else if( GS(id->name)==ID_CU) {
1457                 
1458                 poin= &(icu->curval);
1459                 
1460         }
1461         else if( GS(id->name)==ID_KE) {
1462                 KeyBlock *kb= ((Key *)id)->block.first;
1463                 
1464                 for(; kb; kb= kb->next)
1465                         if(kb->adrcode==icu->adrcode)
1466                                 break;
1467                 if(kb)
1468                         poin= &(kb->curval);
1469                 
1470         }
1471         else if(GS(id->name)==ID_WO) {
1472                 
1473                 wo= (World *)id;
1474                 
1475                 switch(icu->adrcode) {
1476                 case WO_HOR_R:
1477                         poin= &(wo->horr); break;
1478                 case WO_HOR_G:
1479                         poin= &(wo->horg); break;
1480                 case WO_HOR_B:
1481                         poin= &(wo->horb); break;
1482                 case WO_ZEN_R:
1483                         poin= &(wo->zenr); break;
1484                 case WO_ZEN_G:
1485                         poin= &(wo->zeng); break;
1486                 case WO_ZEN_B:
1487                         poin= &(wo->zenb); break;
1488
1489                 case WO_EXPOS:
1490                         poin= &(wo->exposure); break;
1491
1492                 case WO_MISI:
1493                         poin= &(wo->misi); break;
1494                 case WO_MISTDI:
1495                         poin= &(wo->mistdist); break;
1496                 case WO_MISTSTA:
1497                         poin= &(wo->miststa); break;
1498                 case WO_MISTHI:
1499                         poin= &(wo->misthi); break;
1500
1501                 case WO_STAR_R:
1502                         poin= &(wo->starr); break;
1503                 case WO_STAR_G:
1504                         poin= &(wo->starg); break;
1505                 case WO_STAR_B:
1506                         poin= &(wo->starb); break;
1507
1508                 case WO_STARDIST:
1509                         poin= &(wo->stardist); break;
1510                 case WO_STARSIZE:
1511                         poin= &(wo->starsize); break;
1512                 }
1513
1514                 if(poin==NULL) {
1515                         mtex= 0;
1516                         if(icu->adrcode & MA_MAP1) mtex= wo->mtex[0];
1517                         else if(icu->adrcode & MA_MAP2) mtex= wo->mtex[1];
1518                         else if(icu->adrcode & MA_MAP3) mtex= wo->mtex[2];
1519                         else if(icu->adrcode & MA_MAP4) mtex= wo->mtex[3];
1520                         else if(icu->adrcode & MA_MAP5) mtex= wo->mtex[4];
1521                         else if(icu->adrcode & MA_MAP6) mtex= wo->mtex[5];
1522                         else if(icu->adrcode & MA_MAP7) mtex= wo->mtex[6];
1523                         else if(icu->adrcode & MA_MAP8) mtex= wo->mtex[7];
1524                         else if(icu->adrcode & MA_MAP9) mtex= wo->mtex[8];
1525                         else if(icu->adrcode & MA_MAP10) mtex= wo->mtex[9];
1526                         else if(icu->adrcode & MA_MAP11) mtex= wo->mtex[10];
1527                         else if(icu->adrcode & MA_MAP12) mtex= wo->mtex[11];
1528                         else if(icu->adrcode & MA_MAP13) mtex= wo->mtex[12];
1529                         else if(icu->adrcode & MA_MAP14) mtex= wo->mtex[13];
1530                         else if(icu->adrcode & MA_MAP15) mtex= wo->mtex[14];
1531                         else if(icu->adrcode & MA_MAP16) mtex= wo->mtex[15];
1532                         else if(icu->adrcode & MA_MAP17) mtex= wo->mtex[16];
1533                         else if(icu->adrcode & MA_MAP18) mtex= wo->mtex[17];
1534                         if(mtex) {
1535                                 poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
1536                         }
1537                 }
1538         }
1539         else if( GS(id->name)==ID_LA) {
1540                 
1541                 la= (Lamp *)id;
1542         
1543                 switch(icu->adrcode) {
1544                 case LA_ENERGY:
1545                         poin= &(la->energy); break;             
1546                 case LA_COL_R:
1547                         poin= &(la->r); break;
1548                 case LA_COL_G:
1549                         poin= &(la->g); break;
1550                 case LA_COL_B:
1551                         poin= &(la->b); break;
1552                 case LA_DIST:
1553                         poin= &(la->dist); break;               
1554                 case LA_SPOTSI:
1555                         poin= &(la->spotsize); break;
1556                 case LA_SPOTBL:
1557                         poin= &(la->spotblend); break;
1558                 case LA_QUAD1:
1559                         poin= &(la->att1); break;
1560                 case LA_QUAD2:
1561                         poin= &(la->att2); break;
1562                 case LA_HALOINT:
1563                         poin= &(la->haint); break;
1564                 }
1565                 
1566                 if(poin==NULL) {
1567                         mtex= 0;
1568                         if(icu->adrcode & MA_MAP1) mtex= la->mtex[0];
1569                         else if(icu->adrcode & MA_MAP2) mtex= la->mtex[1];
1570                         else if(icu->adrcode & MA_MAP3) mtex= la->mtex[2];
1571                         else if(icu->adrcode & MA_MAP4) mtex= la->mtex[3];
1572                         else if(icu->adrcode & MA_MAP5) mtex= la->mtex[4];
1573                         else if(icu->adrcode & MA_MAP6) mtex= la->mtex[5];
1574                         else if(icu->adrcode & MA_MAP7) mtex= la->mtex[6];
1575                         else if(icu->adrcode & MA_MAP8) mtex= la->mtex[7];
1576                         else if(icu->adrcode & MA_MAP9) mtex= la->mtex[8];
1577                         else if(icu->adrcode & MA_MAP10) mtex= la->mtex[9];
1578                         else if(icu->adrcode & MA_MAP11) mtex= la->mtex[10];
1579                         else if(icu->adrcode & MA_MAP12) mtex= la->mtex[11];
1580                         else if(icu->adrcode & MA_MAP13) mtex= la->mtex[12];
1581                         else if(icu->adrcode & MA_MAP14) mtex= la->mtex[13];
1582                         else if(icu->adrcode & MA_MAP15) mtex= la->mtex[14];
1583                         else if(icu->adrcode & MA_MAP16) mtex= la->mtex[15];
1584                         else if(icu->adrcode & MA_MAP17) mtex= la->mtex[16];
1585                         else if(icu->adrcode & MA_MAP18) mtex= la->mtex[17];
1586                         
1587                         if(mtex) {
1588                                 poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
1589                         }
1590                 }
1591         }
1592         else if(GS(id->name)==ID_CA) {
1593                 Camera *ca= (Camera *)id;
1594                 
1595                 /* yafray: aperture & focal distance params */
1596                 switch(icu->adrcode) {
1597                 case CAM_LENS:
1598                         if(ca->type==CAM_ORTHO)
1599                                 poin= &(ca->ortho_scale);
1600                         else
1601                                 poin= &(ca->lens); 
1602                         break;
1603                 case CAM_STA:
1604                         poin= &(ca->clipsta); break;
1605                 case CAM_END:
1606                         poin= &(ca->clipend); break;
1607                 case CAM_YF_APERT:
1608                         poin= &(ca->YF_aperture); break;
1609                 case CAM_YF_FDIST:
1610                         poin= &(ca->YF_dofdist); break;
1611                 case CAM_SHIFT_X:
1612                         poin= &(ca->shiftx); break;
1613                 case CAM_SHIFT_Y:
1614                         poin= &(ca->shifty); break;
1615                 }
1616         }
1617         else if(GS(id->name)==ID_SO) {
1618                 bSound *snd= (bSound *)id;
1619                 
1620                 switch(icu->adrcode) {
1621                 case SND_VOLUME:
1622                         poin= &(snd->volume); break;
1623                 case SND_PITCH:
1624                         poin= &(snd->pitch); break;
1625                 case SND_PANNING:
1626                         poin= &(snd->panning); break;
1627                 case SND_ATTEN:
1628                         poin= &(snd->attenuation); break;
1629                 }
1630         }
1631         else if( GS(id->name)==ID_PA) {
1632                 
1633                 part= (ParticleSettings *)id;
1634                 
1635                 switch(icu->adrcode) {
1636                 case PART_EMIT_FREQ:
1637                 case PART_EMIT_LIFE:
1638                 case PART_EMIT_VEL:
1639                 case PART_EMIT_AVE:
1640                 case PART_EMIT_SIZE:
1641                         poin= NULL; break;
1642                 case PART_CLUMP:
1643                         poin= &(part->clumpfac); break;
1644                 case PART_AVE:
1645                         poin= &(part->avefac); break;
1646                 case PART_SIZE:
1647                         poin= &(part->size); break;
1648                 case PART_DRAG:
1649                         poin= &(part->dragfac); break;
1650                 case PART_BROWN:
1651                         poin= &(part->brownfac); break;
1652                 case PART_DAMP:
1653                         poin= &(part->dampfac); break;
1654                 case PART_LENGTH:
1655                         poin= &(part->length); break;
1656                 case PART_GRAV_X:
1657                         poin= &(part->acc[0]); break;
1658                 case PART_GRAV_Y:
1659                         poin= &(part->acc[1]); break;
1660                 case PART_GRAV_Z:
1661                         poin= &(part->acc[2]); break;
1662                 case PART_KINK_AMP:
1663                         poin= &(part->kink_amp); break;
1664                 case PART_KINK_FREQ:
1665                         poin= &(part->kink_freq); break;
1666                 case PART_KINK_SHAPE:
1667                         poin= &(part->kink_shape); break;
1668                 case PART_BB_TILT:
1669                         poin= &(part->bb_tilt); break;
1670                 case PART_PD_FSTR:
1671                         poin= (part->pd?(&(part->pd->f_strength)):NULL); break;
1672                 case PART_PD_FFALL:
1673                         poin= (part->pd?(&(part->pd->f_power)):NULL); break;
1674                 case PART_PD_FMAXD:
1675                         poin= (part->pd?(&(part->pd->maxdist)):NULL); break;
1676                 case PART_PD2_FSTR:
1677                         poin= (part->pd2?(&(part->pd2->f_strength)):NULL); break;
1678                 case PART_PD2_FFALL:
1679                         poin= (part->pd2?(&(part->pd2->f_power)):NULL); break;
1680                 case PART_PD2_FMAXD:
1681                         poin= (part->pd2?(&(part->pd2->maxdist)):NULL); break;
1682                 }
1683         }
1684
1685         return poin;
1686 }
1687
1688 void set_icu_vars(IpoCurve *icu)
1689 {
1690         /* defaults. 0.0 for y-extents makes these ignored */
1691         icu->ymin= icu->ymax= 0.0;
1692         icu->ipo= IPO_BEZ;
1693         
1694         if(icu->blocktype==ID_OB) {
1695         
1696                 if(icu->adrcode==OB_LAY) {
1697                         icu->ipo= IPO_CONST;
1698                         icu->vartype= IPO_BITS;
1699                 }
1700                 
1701         }
1702         else if(icu->blocktype==ID_MA) {
1703                 
1704                 if(icu->adrcode < MA_MAP1) {
1705                         switch(icu->adrcode) {
1706                         case MA_HASIZE:
1707                                 icu->ymax= 10000.0; break;
1708                         case MA_HARD:
1709                                 icu->ymax= 511.0; break;
1710                         case MA_SPEC:
1711                                 icu->ymax= 2.0; break;
1712                         case MA_MODE:
1713                                 icu->ipo= IPO_CONST;
1714                                 icu->vartype= IPO_BITS; break;
1715                         case MA_RAYM:
1716                                 icu->ymax= 1.0; break;
1717                         case MA_TRANSLU:
1718                                 icu->ymax= 1.0; break;
1719                         case MA_IOR:
1720                                 icu->ymin= 1.0;
1721                                 icu->ymax= 3.0; break;
1722                         case MA_FRESMIR:
1723                                 icu->ymax= 5.0; break;
1724                         case MA_FRESMIRI:
1725                                 icu->ymin= 1.0;
1726                                 icu->ymax= 5.0; break;
1727                         case MA_FRESTRA:
1728                                 icu->ymax= 5.0; break;
1729                         case MA_FRESTRAI:
1730                                 icu->ymin= 1.0;
1731                                 icu->ymax= 5.0; break;
1732                         case MA_ADD:
1733                                 icu->ymax= 1.0; break;
1734                         case MA_EMIT:
1735                                 icu->ymax= 2.0; break;
1736                         default:
1737                                 icu->ymax= 1.0; break;
1738                         }
1739                 }
1740                 else {
1741                         switch(icu->adrcode & (MA_MAP1-1)) {
1742                         case MAP_OFS_X:
1743                         case MAP_OFS_Y:
1744                         case MAP_OFS_Z:
1745                         case MAP_SIZE_X:
1746                         case MAP_SIZE_Y:
1747                         case MAP_SIZE_Z:
1748                                 icu->ymax= 1000.0;
1749                                 icu->ymin= -1000.0;
1750                         
1751                                 break;
1752                         case MAP_R:
1753                         case MAP_G:
1754                         case MAP_B:
1755                         case MAP_DVAR:
1756                         case MAP_COLF:
1757                         case MAP_VARF:
1758                         case MAP_DISP:
1759                                 icu->ymax= 1.0;
1760                                 break;
1761                         case MAP_NORF:
1762                                 icu->ymax= 25.0;
1763                                 break;
1764                         }
1765                 }
1766         }
1767         else if(icu->blocktype==ID_TE) {
1768                 switch(icu->adrcode & (MA_MAP1-1)) {
1769                         case TE_NSIZE:
1770                                 icu->ymin= 0.0001;
1771                                 icu->ymax= 2.0; break;
1772                         case TE_NDEPTH:
1773                                 icu->vartype= IPO_SHORT;
1774                                 icu->ipo= IPO_CONST;
1775                                 icu->ymax= 6.0; break;
1776                         case TE_NTYPE:
1777                                 icu->vartype= IPO_SHORT;
1778                                 icu->ipo= IPO_CONST;
1779                                 icu->ymax= 1.0; break;
1780                         case TE_TURB:
1781                                 icu->ymax= 200.0; break;
1782                         case TE_VNW1:
1783                         case TE_VNW2:
1784                         case TE_VNW3:
1785                         case TE_VNW4:
1786                                 icu->ymax= 2.0;
1787                                 icu->ymin= -2.0; break;
1788                         case TE_VNMEXP:
1789                                 icu->ymax= 10.0;
1790                                 icu->ymin= 0.01; break;
1791                         case TE_VN_DISTM:
1792                                 icu->vartype= IPO_SHORT;
1793                                 icu->ipo= IPO_CONST;
1794                                 icu->ymax= 6.0; break;
1795                         case TE_VN_COLT:
1796                                 icu->vartype= IPO_SHORT;
1797                                 icu->ipo= IPO_CONST;
1798                                 icu->ymax= 3.0; break;
1799                         case TE_ISCA:
1800                                 icu->ymax= 10.0;
1801                                 icu->ymin= 0.01; break;
1802                         case TE_DISTA:
1803                                 icu->ymax= 10.0; break;
1804                         case TE_MG_TYP:
1805                                 icu->vartype= IPO_SHORT;
1806                                 icu->ipo= IPO_CONST;
1807                                 icu->ymax= 6.0; break;
1808                         case TE_MGH:
1809                                 icu->ymin= 0.0001;
1810                                 icu->ymax= 2.0; break;
1811                         case TE_MG_LAC:
1812                         case TE_MG_OFF:
1813                         case TE_MG_GAIN:
1814                                 icu->ymax= 6.0; break;
1815                         case TE_MG_OCT:
1816                                 icu->ymax= 8.0; break;
1817                         case TE_N_BAS1:
1818                         case TE_N_BAS2:
1819                                 icu->vartype= IPO_SHORT;
1820                                 icu->ipo= IPO_CONST;
1821                                 icu->ymax= 8.0; break;
1822                         case TE_COL_R:
1823                                 icu->ymax= 0.0; break;
1824                         case TE_COL_G:
1825                                 icu->ymax= 2.0; break;
1826                         case TE_COL_B:
1827                                 icu->ymax= 2.0; break;
1828                         case TE_BRIGHT:
1829                                 icu->ymax= 2.0; break;
1830                         case TE_CONTRA:
1831                                 icu->ymax= 5.0; break;                          
1832
1833                 }
1834         }
1835         else if(icu->blocktype==ID_SEQ) {
1836         
1837                 icu->ymax= 1.0;
1838                 
1839         }
1840         else if(icu->blocktype==ID_CU) {
1841         
1842                 icu->ymax= 1.0;
1843                 
1844         }
1845         else if(icu->blocktype==ID_WO) {
1846                 
1847                 if(icu->adrcode < MA_MAP1) {
1848                         switch(icu->adrcode) {
1849                         case WO_EXPOS:
1850                                 icu->ymax= 5.0; break;
1851                         case WO_MISTDI:
1852                         case WO_MISTSTA:
1853                         case WO_MISTHI:
1854                         case WO_STARDIST:
1855                         case WO_STARSIZE:
1856                                 break;
1857                                 
1858                         default:
1859                                 icu->ymax= 1.0;
1860                                 break;
1861                         }
1862                 }
1863                 else {
1864                         switch(icu->adrcode & (MA_MAP1-1)) {
1865                         case MAP_OFS_X:
1866                         case MAP_OFS_Y:
1867                         case MAP_OFS_Z:
1868                         case MAP_SIZE_X:
1869                         case MAP_SIZE_Y:
1870                         case MAP_SIZE_Z:
1871                                 icu->ymax= 100.0;
1872                                 icu->ymin= -100.0;
1873                         
1874                                 break;
1875                         case MAP_R:
1876                         case MAP_G:
1877                         case MAP_B:
1878                         case MAP_DVAR:
1879                         case MAP_COLF:
1880                         case MAP_NORF:
1881                         case MAP_VARF:
1882                         case MAP_DISP:
1883                                 icu->ymax= 1.0;
1884                         }
1885                 }
1886         }
1887         else if(icu->blocktype==ID_LA) {
1888                 if(icu->adrcode < MA_MAP1) {
1889                         switch(icu->adrcode) {
1890                         case LA_ENERGY:
1891                         case LA_DIST:
1892                                 break;          
1893         
1894                         case LA_COL_R:
1895                         case LA_COL_G:
1896                         case LA_COL_B:
1897                         case LA_SPOTBL:
1898                         case LA_QUAD1:
1899                         case LA_QUAD2:
1900                                 icu->ymax= 1.0; break;
1901                         case LA_SPOTSI:
1902                                 icu->ymax= 180.0; break;
1903                         case LA_HALOINT:
1904                                 icu->ymax= 5.0; break;
1905                         }
1906                 }
1907                 else {
1908                         switch(icu->adrcode & (MA_MAP1-1)) {
1909                         case MAP_OFS_X:
1910                         case MAP_OFS_Y:
1911                         case MAP_OFS_Z:
1912                         case MAP_SIZE_X:
1913                         case MAP_SIZE_Y:
1914                         case MAP_SIZE_Z:
1915                                 icu->ymax= 100.0;
1916                                 icu->ymin= -100.0;
1917                                 break;
1918                         case MAP_R:
1919                         case MAP_G:
1920                         case MAP_B:
1921                         case MAP_DVAR:
1922                         case MAP_COLF:
1923                         case MAP_NORF:
1924                         case MAP_VARF:
1925                         case MAP_DISP:
1926                                 icu->ymax= 1.0;
1927                         }
1928                 }
1929         }       
1930         else if(icu->blocktype==ID_CA) {
1931
1932                 /* yafray: aperture & focal distance params */
1933                 switch(icu->adrcode) {
1934                 case CAM_LENS:
1935                         icu->ymin= 1.0;
1936                         icu->ymax= 1000.0;
1937                         break;
1938                 case CAM_STA:
1939                         icu->ymin= 0.001f;
1940                         break;
1941                 case CAM_END:
1942                         icu->ymin= 0.1f;
1943                         break;
1944                 case CAM_YF_APERT:
1945                         icu->ymin = 0.0;
1946                         icu->ymax = 2.0;
1947                         break;
1948                 case CAM_YF_FDIST:
1949                         icu->ymin = 0.0;
1950                         icu->ymax = 5000.0;
1951                         break;
1952                         
1953                 case CAM_SHIFT_X:
1954                 case CAM_SHIFT_Y:
1955                         icu->ymin= -2.0f;
1956                         icu->ymax= 2.0f;
1957                         break;
1958                 }
1959         }
1960         else if(icu->blocktype==ID_SO) {
1961
1962                 switch(icu->adrcode) {
1963                 case SND_VOLUME:
1964                         icu->ymin= 0.0;
1965                         icu->ymax= 1.0;
1966                         break;
1967                 case SND_PITCH:
1968                         icu->ymin= -12.0;
1969                         icu->ymin= 12.0;
1970                         break;
1971                 case SND_PANNING:
1972                         icu->ymin= 0.0;
1973                         icu->ymax= 1.0;
1974                         break;
1975                 case SND_ATTEN:
1976                         icu->ymin= 0.0;
1977                         icu->ymin= 1.0;
1978                         break;
1979                 }
1980         }
1981         else if(icu->blocktype==ID_PA){
1982
1983                 switch(icu->adrcode) {
1984                 case PART_EMIT_LIFE:
1985                 case PART_SIZE:
1986                 case PART_KINK_FREQ:
1987                 case PART_EMIT_VEL:
1988                 case PART_EMIT_AVE:
1989                 case PART_EMIT_SIZE:
1990                         icu->ymin= 0.0;
1991                         break;
1992                 case PART_CLUMP:
1993                         icu->ymin= -1.0;
1994                         icu->ymax= 1.0;
1995                         break;
1996                 case PART_DRAG:
1997                 case PART_DAMP:
1998                 case PART_LENGTH:
1999                         icu->ymin= 0.0;
2000                         icu->ymax= 1.0;
2001                         break;
2002                 case PART_KINK_SHAPE:
2003                         icu->ymin= -0.999;
2004                         icu->ymax= 0.999;
2005                         break;
2006                 }
2007         }
2008         else if(icu->blocktype==ID_CO) {
2009                 icu->ymin= 0.0;
2010                 icu->ymax= 1.0f;
2011         }
2012         
2013         /* by default, slider limits will be icu->ymin and icu->ymax */
2014         icu->slide_min= icu->ymin;
2015         icu->slide_max= icu->ymax;
2016 }
2017
2018 /* not for actions or constraints! */
2019 void execute_ipo(ID *id, Ipo *ipo)
2020 {
2021         IpoCurve *icu;
2022         void *poin;
2023         int type;
2024         
2025         if(ipo==NULL) return;
2026         
2027         for(icu= ipo->curve.first; icu; icu= icu->next) {
2028                 poin= get_ipo_poin(id, icu, &type);
2029                 if(poin) write_ipo_poin(poin, type, icu->curval);
2030         }
2031 }
2032
2033 void *get_pchan_ipo_poin(bPoseChannel *pchan, int adrcode)
2034 {
2035         void *poin= NULL;
2036         
2037         switch (adrcode) {
2038                 case AC_QUAT_W:
2039                         poin= &(pchan->quat[0]); 
2040                         pchan->flag |= POSE_ROT;
2041                         break;
2042                 case AC_QUAT_X:
2043                         poin= &(pchan->quat[1]); 
2044                         pchan->flag |= POSE_ROT;
2045                         break;
2046                 case AC_QUAT_Y:
2047                         poin= &(pchan->quat[2]); 
2048                         pchan->flag |= POSE_ROT;
2049                         break;
2050                 case AC_QUAT_Z:
2051                         poin= &(pchan->quat[3]); 
2052                         pchan->flag |= POSE_ROT;
2053                         break;
2054                 case AC_LOC_X:
2055                         poin= &(pchan->loc[0]); 
2056                         pchan->flag |= POSE_LOC;
2057                         break;
2058                 case AC_LOC_Y:
2059                         poin= &(pchan->loc[1]); 
2060                         pchan->flag |= POSE_LOC;
2061                         break;
2062                 case AC_LOC_Z:
2063                         poin= &(pchan->loc[2]); 
2064                         pchan->flag |= POSE_LOC;
2065                         break;                  
2066                 case AC_SIZE_X:
2067                         poin= &(pchan->size[0]); 
2068                         pchan->flag |= POSE_SIZE;
2069                         break;
2070                 case AC_SIZE_Y:
2071                         poin= &(pchan->size[1]); 
2072                         pchan->flag |= POSE_SIZE;
2073                         break;
2074                 case AC_SIZE_Z:
2075                         poin= &(pchan->size[2]); 
2076                         pchan->flag |= POSE_SIZE;
2077                         break;
2078         }
2079         return poin;
2080 }
2081
2082 void execute_action_ipo(bActionChannel *achan, bPoseChannel *pchan)
2083 {
2084
2085         if(achan && achan->ipo) {
2086                 IpoCurve *icu;
2087                 for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
2088                         void *poin= get_pchan_ipo_poin(pchan, icu->adrcode);
2089                         if(poin) {
2090                                 write_ipo_poin(poin, IPO_FLOAT, icu->curval);
2091                                 //printf("execute_action_ipo wrote_ipo_poin: %f\n", icu->curval);
2092                                 //printf("%s has poin %p value %f\n", achan->name, poin, icu->curval);
2093                         }
2094                 }
2095         }
2096 }
2097
2098 /* exception: it does calc for objects...
2099  * now find out why this routine was used anyway!
2100  */
2101 void do_ipo_nocalc(Ipo *ipo)
2102 {
2103         Object *ob;
2104         Material *ma;
2105         Tex *tex;
2106         World *wo;
2107         Lamp *la;
2108         Camera *ca;
2109         bSound *snd;
2110         
2111         if(ipo==NULL) return;
2112         
2113         switch(ipo->blocktype) {
2114         case ID_OB:
2115                 ob= G.main->object.first;
2116                 while(ob) {
2117                         if(ob->ipo==ipo) {
2118                                 do_ob_ipo(ob);
2119                                 /* execute_ipo((ID *)ob, ipo); */
2120                         }
2121                         ob= ob->id.next;
2122                 }
2123                 break;
2124         case ID_MA:
2125                 ma= G.main->mat.first;
2126                 while(ma) {
2127                         if(ma->ipo==ipo) execute_ipo((ID *)ma, ipo);
2128                         ma= ma->id.next;
2129                 }
2130                 break;
2131         case ID_TE:
2132                 tex= G.main->tex.first;
2133                 while(tex) {
2134                         if(tex->ipo==ipo) execute_ipo((ID *)tex, ipo);
2135                         tex=tex->id.next;
2136                 }
2137                 break;
2138         case ID_WO:
2139                 wo= G.main->world.first;
2140                 while(wo) {
2141                         if(wo->ipo==ipo) execute_ipo((ID *)wo, ipo);
2142                         wo= wo->id.next;
2143                 }
2144                 break;
2145         case ID_LA:
2146                 la= G.main->lamp.first;
2147                 while(la) {
2148                         if(la->ipo==ipo) execute_ipo((ID *)la, ipo);
2149                         la= la->id.next;
2150                 }
2151                 break;
2152         case ID_CA:
2153                 ca= G.main->camera.first;
2154                 while(ca) {
2155                         if(ca->ipo==ipo) execute_ipo((ID *)ca, ipo);
2156                         ca= ca->id.next;
2157                 }
2158                 break;
2159         case ID_SO:
2160                 snd= G.main->sound.first;
2161                 while(snd) {
2162                         if(snd->ipo==ipo) execute_ipo((ID *)snd, ipo);
2163                         snd= snd->id.next;
2164                 }
2165                 break;
2166         }
2167 }
2168
2169 void do_ipo(Ipo *ipo)
2170 {
2171         if(ipo) {
2172                 float ctime= frame_to_float(G.scene->r.cfra);
2173                 calc_ipo(ipo, ctime);
2174         
2175                 do_ipo_nocalc(ipo);
2176         }
2177 }
2178
2179
2180
2181 void do_mat_ipo(Material *ma)
2182 {
2183         float ctime;
2184         
2185         if(ma==NULL || ma->ipo==NULL) return;
2186         
2187         ctime= frame_to_float(G.scene->r.cfra);
2188         /* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */
2189
2190         calc_ipo(ma->ipo, ctime);
2191         
2192         execute_ipo((ID *)ma, ma->ipo);
2193 }
2194
2195 void do_ob_ipo(Object *ob)
2196 {
2197         float ctime;
2198         unsigned int lay;
2199         
2200         if(ob->ipo==NULL) return;
2201
2202         /* do not set ob->ctime here: for example when parent in invisible layer */
2203         
2204         ctime= bsystem_time(ob, (float) G.scene->r.cfra, 0.0);
2205
2206         calc_ipo(ob->ipo, ctime);
2207
2208         /* Patch: remember localview */
2209         lay= ob->lay & 0xFF000000;
2210         
2211         execute_ipo((ID *)ob, ob->ipo);
2212
2213         ob->lay |= lay;
2214         if(ob->id.name[2]=='S' && ob->id.name[3]=='C' && ob->id.name[4]=='E') {
2215                 if(strcmp(G.scene->id.name+2, ob->id.name+6)==0) {
2216                         G.scene->lay= ob->lay;
2217                         copy_view3d_lock(0);
2218                         /* no redraw here! creates too many calls */
2219                 }
2220         }
2221 }
2222
2223 void do_ob_ipodrivers(Object *ob, Ipo *ipo, float ctime)
2224 {
2225         IpoCurve *icu;
2226         void *poin;
2227         int type;
2228         
2229         for(icu= ipo->curve.first; icu; icu= icu->next) {
2230                 if(icu->driver) {
2231                         icu->curval= eval_icu(icu, ctime);
2232                         poin= get_ipo_poin((ID *)ob, icu, &type);
2233                         if(poin) write_ipo_poin(poin, type, icu->curval);
2234                 }
2235         }
2236 }
2237
2238 void do_seq_ipo(Sequence *seq, int cfra)
2239 {
2240         float ctime, div;
2241         
2242         /* seq_ipo has an exception: calc both fields immediately */
2243         
2244         if(seq->ipo) {
2245                 if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2246                         ctime = frame_to_float(cfra);
2247                         div = 1.0;
2248                 } else {
2249                         ctime= frame_to_float(cfra - seq->startdisp);
2250                         div= (seq->enddisp - seq->startdisp)/100.0f;
2251                         if(div==0.0) return;
2252                 }
2253                 
2254                 /* 2nd field */
2255                 calc_ipo(seq->ipo, (ctime+0.5f)/div);
2256                 execute_ipo((ID *)seq, seq->ipo);
2257                 seq->facf1= seq->facf0;
2258
2259                 /* 1st field */
2260                 calc_ipo(seq->ipo, ctime/div);
2261                 execute_ipo((ID *)seq, seq->ipo);
2262
2263         }
2264         else seq->facf1= seq->facf0= 1.0f;
2265 }
2266
2267 int has_ipo_code(Ipo *ipo, int code)
2268 {
2269         IpoCurve *icu;
2270         
2271         if(ipo==NULL) return 0;
2272         
2273         for(icu= ipo->curve.first; icu; icu= icu->next) {
2274                 if(icu->adrcode==code) return 1;
2275         }
2276         return 0;
2277 }
2278
2279 void do_all_data_ipos()
2280 {
2281         Material *ma;
2282         Tex *tex;
2283         World *wo;
2284         Ipo *ipo;
2285         Lamp *la;
2286         Key *key;
2287         Camera *ca;
2288         bSound *snd;
2289         Sequence *seq;
2290         Editing *ed;
2291         Base *base;
2292         float ctime;
2293
2294         ctime= frame_to_float(G.scene->r.cfra);
2295         
2296         /* this exception cannot be depgraphed yet... what todo with objects in other layers?... */
2297         for(base= G.scene->base.first; base; base= base->next) {
2298                 /* only update layer when an ipo */
2299                 if( has_ipo_code(base->object->ipo, OB_LAY) ) {
2300                         do_ob_ipo(base->object);
2301                         base->lay= base->object->lay;
2302                 }
2303         }
2304         
2305         /* layers for the set...*/
2306         if(G.scene->set) {
2307                 for(base= G.scene->set->base.first; base; base= base->next) {
2308                         if( has_ipo_code(base->object->ipo, OB_LAY) ) {
2309                                 do_ob_ipo(base->object);
2310                                 base->lay= base->object->lay;
2311                         }
2312                 }
2313         }
2314         
2315         
2316         ipo= G.main->ipo.first;
2317         while(ipo) {
2318                 if(ipo->id.us && ipo->blocktype!=ID_OB) {
2319                         calc_ipo(ipo, ctime);
2320                 }
2321                 ipo= ipo->id.next;
2322         }
2323
2324         for(tex= G.main->tex.first; tex; tex= tex->id.next) {
2325                 if(tex->ipo) execute_ipo((ID *)tex, tex->ipo);
2326         }
2327
2328         for(ma= G.main->mat.first; ma; ma= ma->id.next) {
2329                 if(ma->ipo) execute_ipo((ID *)ma, ma->ipo);
2330         }
2331
2332         for(wo= G.main->world.first; wo; wo= wo->id.next) {
2333                 if(wo->ipo) execute_ipo((ID *)wo, wo->ipo);
2334         }
2335         
2336         for(key= G.main->key.first; key; key= key->id.next) {
2337                 if(key->ipo) execute_ipo((ID *)key, key->ipo);
2338         }
2339         
2340         la= G.main->lamp.first;
2341         while(la) {
2342                 if(la->ipo) execute_ipo((ID *)la, la->ipo);
2343                 la= la->id.next;
2344         }
2345
2346         ca= G.main->camera.first;
2347         while(ca) {
2348                 if(ca->ipo) execute_ipo((ID *)ca, ca->ipo);
2349                 ca= ca->id.next;
2350         }
2351
2352         snd= G.main->sound.first;
2353         while(snd) {
2354                 if(snd->ipo) execute_ipo((ID *)snd, snd->ipo);
2355                 snd= snd->id.next;
2356         }
2357
2358         /* process FAC Ipos used as volume envelopes */
2359         ed= G.scene->ed;
2360         if (ed) {
2361                 seq= ed->seqbasep->first;
2362                 while(seq) {
2363                         if ((seq->type == SEQ_RAM_SOUND
2364                              || seq->type == SEQ_HD_SOUND) && (seq->ipo) && 
2365                                 (seq->startdisp<=G.scene->r.cfra+2) && 
2366                             (seq->enddisp>G.scene->r.cfra)) 
2367                                         do_seq_ipo(seq, G.scene->r.cfra);
2368                         seq= seq->next;
2369                 }
2370         }
2371
2372 }
2373
2374
2375 int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime)
2376 {
2377         IpoCurve *icu;
2378
2379         if(ipo==NULL) return 0;
2380
2381         for(icu= ipo->curve.first; icu; icu= icu->next) {
2382                 if(icu->adrcode == adrcode) {
2383                         if(icu->flag & IPO_LOCK);
2384                         else calc_icu(icu, *ctime);
2385                         
2386                         *ctime= icu->curval;
2387                         return 1;
2388                 }
2389         }
2390         
2391         return 0;
2392 }
2393
2394
2395 /* ************************** */
2396
2397 void clear_delta_obipo(Ipo *ipo)
2398 {
2399         Object *ob;
2400         
2401         if(ipo==NULL) return;
2402         
2403         ob= G.main->object.first;
2404         while(ob) {
2405                 if(ob->id.lib==NULL) {
2406                         if(ob->ipo==ipo) {
2407                                 memset(&ob->dloc, 0, 12);
2408                                 memset(&ob->drot, 0, 12);
2409                                 memset(&ob->dsize, 0, 12);
2410                         }
2411                 }
2412                 ob= ob->id.next;
2413         }
2414 }
2415
2416 void add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
2417 {
2418         CfraElem *ce, *cen;
2419         
2420         ce= lb->first;
2421         while(ce) {
2422                 
2423                 if( ce->cfra==bezt->vec[1][0] ) {
2424                         /* do because of double keys */
2425                         if(bezt->f2 & SELECT) ce->sel= bezt->f2;
2426                         return;
2427                 }
2428                 else if(ce->cfra > bezt->vec[1][0]) break;
2429                 
2430                 ce= ce->next;
2431         }       
2432         
2433         cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); 
2434         if(ce) BLI_insertlinkbefore(lb, ce, cen);
2435         else BLI_addtail(lb, cen);
2436
2437         cen->cfra= bezt->vec[1][0];
2438         cen->sel= bezt->f2;
2439 }
2440
2441
2442
2443 void make_cfra_list(Ipo *ipo, ListBase *elems)
2444 {
2445         IpoCurve *icu;
2446         BezTriple *bezt;
2447         int a;
2448         
2449         if(ipo->blocktype==ID_OB) {
2450                 for(icu= ipo->curve.first; icu; icu= icu->next) {
2451                         if(icu->flag & IPO_VISIBLE) {
2452                                 switch(icu->adrcode) {
2453                                 case OB_DLOC_X:
2454                                 case OB_DLOC_Y:
2455                                 case OB_DLOC_Z:
2456                                 case OB_DROT_X:
2457                                 case OB_DROT_Y:
2458                                 case OB_DROT_Z:
2459                                 case OB_DSIZE_X:
2460                                 case OB_DSIZE_Y:
2461                                 case OB_DSIZE_Z:
2462
2463                                 case OB_LOC_X:
2464                                 case OB_LOC_Y:
2465                                 case OB_LOC_Z:
2466                                 case OB_ROT_X:
2467                                 case OB_ROT_Y:
2468                                 case OB_ROT_Z:
2469                                 case OB_SIZE_X:
2470                                 case OB_SIZE_Y:
2471                                 case OB_SIZE_Z:
2472                                 case OB_PD_FSTR:
2473                                 case OB_PD_FFALL:
2474                                 case OB_PD_SDAMP:
2475                                 case OB_PD_RDAMP:
2476                                 case OB_PD_PERM:
2477                                 case OB_PD_FMAXD:
2478                                         bezt= icu->bezt;
2479                                         if(bezt) {
2480                                                 a= icu->totvert;
2481                                                 while(a--) {
2482                                                         add_to_cfra_elem(elems, bezt);
2483                                                         bezt++;
2484                                                 }
2485                                         }
2486                                         break;
2487                                 }
2488                         }
2489                 }
2490         }
2491         else if(ipo->blocktype==ID_AC) {
2492                 for(icu= ipo->curve.first; icu; icu= icu->next) {
2493                         if(icu->flag & IPO_VISIBLE) {
2494                                 switch(icu->adrcode) {
2495                                 case AC_LOC_X:
2496                                 case AC_LOC_Y:
2497                                 case AC_LOC_Z:
2498                                 case AC_SIZE_X:
2499                                 case AC_SIZE_Y:
2500                                 case AC_SIZE_Z:
2501                                 case AC_QUAT_W:
2502                                 case AC_QUAT_X:
2503                                 case AC_QUAT_Y:
2504                                 case AC_QUAT_Z:
2505                                         bezt= icu->bezt;
2506                                         if(bezt) {
2507                                                 a= icu->totvert;
2508                                                 while(a--) {
2509                                                         add_to_cfra_elem(elems, bezt);
2510                                                         bezt++;
2511                                                 }
2512                                         }
2513                                         break;
2514                                 }
2515                         }
2516                 }
2517         }
2518         else {
2519                 for(icu= ipo->curve.first; icu; icu= icu->next) {
2520                         if(icu->flag & IPO_VISIBLE) {
2521                                 bezt= icu->bezt;
2522                                 if(bezt) {
2523                                         a= icu->totvert;
2524                                         while(a--) {
2525                                                 add_to_cfra_elem(elems, bezt);
2526                                                 bezt++;
2527                                         }
2528                                 }
2529                         }
2530                 }
2531         }
2532
2533         /* what's the point of this little block of code?  */
2534 #if 0
2535         if(ipo->showkey==0) {
2536                 /* deselect all keys */
2537                 ce= elems->first;
2538                 while(ce) {
2539                         ce->sel= 0;
2540                         ce= ce->next;
2541                 }
2542         }
2543 #endif
2544 }
2545
2546 /* *********************** INTERFACE FOR KETSJI ********** */
2547
2548
2549 int IPO_GetChannels(Ipo *ipo, IPO_Channel *channels)
2550 {
2551         /* channels is max 32 items, allocated by calling function */   
2552
2553         IpoCurve *icu;
2554         int total=0;
2555         
2556         if(ipo==NULL) return 0;
2557         
2558         for(icu= ipo->curve.first; icu; icu= icu->next) {
2559                 channels[total]= icu->adrcode;
2560                 total++;
2561                 if(total>31) break;
2562         }
2563         
2564         return total;
2565 }
2566
2567
2568
2569 /* Get the float value for channel 'channel' at time 'ctime' */
2570
2571 float IPO_GetFloatValue(Ipo *ipo, IPO_Channel channel, float ctime)
2572 {
2573         if(ipo==NULL) return 0;
2574         
2575         calc_ipo_spec(ipo, channel, &ctime);
2576         
2577         if (OB_ROT_X <= channel && channel <= OB_DROT_Z) {
2578                 ctime *= (float)(M_PI_2/9.0); 
2579         }
2580
2581         return ctime;
2582 }