2.5
[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): 2008, Joshua Leung (IPO System cleanup)
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_utildefines.h"
64
65 #include "BKE_action.h"
66 #include "BKE_blender.h"
67 #include "BKE_curve.h"
68 #include "BKE_constraint.h"
69 #include "BKE_global.h"
70 #include "BKE_ipo.h"
71 #include "BKE_library.h"
72 #include "BKE_main.h"
73 #include "BKE_mesh.h"
74 #include "BKE_object.h"
75
76 #ifndef DISABLE_PYTHON
77 #include "BPY_extern.h" /* for BPY_pydriver_eval() */
78 #endif
79
80 #define SMALL -1.0e-10
81
82 /* ***************************** Adrcode Blocktype Defines ********************************* */
83
84 /* This array concept was meant to make sure that defines such as OB_LOC_X
85    don't have to be enumerated, also for backward compatibility, future changes,
86    and to enable it all can be accessed with a for-next loop.
87    
88    This should whole adrcode system should eventually be replaced by a proper Data API
89 */
90
91
92 int co_ar[CO_TOTIPO]= {
93         CO_ENFORCE, CO_HEADTAIL
94 };
95
96 int ob_ar[OB_TOTIPO]= {
97         OB_LOC_X, OB_LOC_Y, OB_LOC_Z, OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z, 
98         OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z, 
99         OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z, 
100         OB_LAY, OB_TIME, OB_COL_R, OB_COL_G, OB_COL_B, OB_COL_A,
101         OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM, OB_PD_FMAXD
102 };
103
104 int ac_ar[AC_TOTIPO]= {
105         AC_LOC_X, AC_LOC_Y, AC_LOC_Z,
106         AC_EUL_X, AC_EUL_Y, AC_EUL_Z,
107         AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z,
108         AC_SIZE_X, AC_SIZE_Y, AC_SIZE_Z
109 };
110
111 int ma_ar[MA_TOTIPO]= {
112         MA_COL_R, MA_COL_G, MA_COL_B, 
113         MA_SPEC_R, MA_SPEC_G, MA_SPEC_B, 
114         MA_MIR_R, MA_MIR_G, MA_MIR_B,
115         MA_REF, MA_ALPHA, MA_EMIT, MA_AMB, 
116         MA_SPEC, MA_HARD, MA_SPTR, MA_IOR, 
117         MA_MODE, MA_HASIZE, MA_TRANSLU, MA_RAYM,
118         MA_FRESMIR, MA_FRESMIRI, MA_FRESTRA, MA_FRESTRAI, MA_ADD,
119         
120         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
121         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
122         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
123         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF, MA_MAP1+MAP_DISP
124 };
125
126 int te_ar[TE_TOTIPO] ={
127         
128         TE_NSIZE, TE_NDEPTH, TE_NTYPE, TE_TURB,
129         
130         TE_VNW1, TE_VNW2, TE_VNW3, TE_VNW4,
131         TE_VNMEXP, TE_VN_COLT, TE_VN_DISTM,
132         
133         TE_ISCA, TE_DISTA,
134         
135         TE_MG_TYP, TE_MGH, TE_MG_LAC, TE_MG_OCT, TE_MG_OFF, TE_MG_GAIN,
136         
137         TE_N_BAS1, TE_N_BAS2,
138         
139         TE_COL_R, TE_COL_G, TE_COL_B, TE_BRIGHT, TE_CONTRA
140 };
141
142 int seq_ar[SEQ_TOTIPO]= {
143         SEQ_FAC1
144 };
145
146 int cu_ar[CU_TOTIPO]= {
147         CU_SPEED
148 };
149
150 int wo_ar[WO_TOTIPO]= {
151         WO_HOR_R, WO_HOR_G, WO_HOR_B, WO_ZEN_R, WO_ZEN_G, WO_ZEN_B, 
152         WO_EXPOS, WO_MISI, WO_MISTDI, WO_MISTSTA, WO_MISTHI,
153         WO_STAR_R, WO_STAR_G, WO_STAR_B, WO_STARDIST, WO_STARSIZE, 
154
155         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
156         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
157         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
158         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF
159 };
160
161 int la_ar[LA_TOTIPO]= {
162         LA_ENERGY, LA_COL_R, LA_COL_G, LA_COL_B, 
163         LA_DIST, LA_SPOTSI, LA_SPOTBL, 
164         LA_QUAD1, LA_QUAD2, LA_HALOINT,  
165
166         MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z, 
167         MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z, 
168         MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
169         MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF
170 };
171
172 /* yafray: aperture & focal distance curves added */
173 /* qdn: FDIST now available to Blender as well for defocus node */
174 int cam_ar[CAM_TOTIPO]= {
175         CAM_LENS, CAM_STA, CAM_END, CAM_YF_APERT, CAM_YF_FDIST, CAM_SHIFT_X, CAM_SHIFT_Y
176 };
177
178 int snd_ar[SND_TOTIPO]= {
179         SND_VOLUME, SND_PITCH, SND_PANNING, SND_ATTEN
180 };
181
182 int fluidsim_ar[FLUIDSIM_TOTIPO]= {
183         FLUIDSIM_VISC, FLUIDSIM_TIME,
184         FLUIDSIM_GRAV_X , FLUIDSIM_GRAV_Y , FLUIDSIM_GRAV_Z ,
185         FLUIDSIM_VEL_X  , FLUIDSIM_VEL_Y  , FLUIDSIM_VEL_Z  ,
186         FLUIDSIM_ACTIVE,
187         FLUIDSIM_ATTR_FORCE_STR, FLUIDSIM_ATTR_FORCE_RADIUS,
188         FLUIDSIM_VEL_FORCE_STR, FLUIDSIM_VEL_FORCE_RADIUS,
189 };
190
191 int part_ar[PART_TOTIPO]= {
192         PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, PART_EMIT_SIZE,
193         PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, PART_CLUMP,
194     PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, PART_KINK_SHAPE,
195         PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD, PART_PD2_FSTR, PART_PD2_FFALL, PART_PD2_FMAXD
196 };
197
198 /* ************************** Data-Level Functions ************************* */
199
200 /* ---------------------- Freeing --------------------------- */
201
202 /* frees the ipo curve itself too */
203 void free_ipo_curve (IpoCurve *icu) 
204 {
205         if (icu == NULL) 
206                 return;
207         
208         if (icu->bezt) 
209                 MEM_freeN(icu->bezt);
210         if (icu->driver) 
211                 MEM_freeN(icu->driver);
212         
213         MEM_freeN(icu);
214 }
215
216 /* do not free ipo itself */
217 void free_ipo (Ipo *ipo)
218 {
219         IpoCurve *icu, *icn;
220         
221         if (ipo == NULL) 
222                 return;
223         
224         for (icu= ipo->curve.first; icu; icu= icn) {
225                 icn= icu->next;
226                 
227                 /* must remove the link before freeing, as the curve is freed too */
228                 BLI_remlink(&ipo->curve, icu);
229                 free_ipo_curve(icu);
230         }
231 }
232
233 /* ---------------------- Init --------------------------- */
234
235 /* on adding new ipos, or for empty views */
236 void ipo_default_v2d_cur (int blocktype, rctf *cur)
237 {
238         switch (blocktype) {
239         case ID_CA:
240                 cur->xmin= (float)G.scene->r.sfra;
241                 cur->xmax= (float)G.scene->r.efra;
242                 cur->ymin= 0.0f;
243                 cur->ymax= 100.0f;
244                 break;
245                 
246         case ID_MA: case ID_WO: case ID_LA: 
247         case ID_CU: case ID_CO:
248                 cur->xmin= (float)(G.scene->r.sfra - 0.1f);
249                 cur->xmax= (float)G.scene->r.efra;
250                 cur->ymin= (float)-0.1f;
251                 cur->ymax= (float)+1.1f;
252                 break;
253                 
254         case ID_TE:
255                 cur->xmin= (float)(G.scene->r.sfra - 0.1f);
256                 cur->xmax= (float)G.scene->r.efra;
257                 cur->ymin= (float)-0.1f;
258                 cur->ymax= (float)+1.1f;
259                 break;
260                 
261         case ID_SEQ:
262                 cur->xmin= -5.0f;
263                 cur->xmax= 105.0f;
264                 cur->ymin= (float)-0.1f;
265                 cur->ymax= (float)+1.1f;
266                 break;
267                 
268         case ID_KE:
269                 cur->xmin= (float)(G.scene->r.sfra - 0.1f);
270                 cur->xmax= (float)G.scene->r.efra;
271                 cur->ymin= (float)-0.1f;
272                 cur->ymax= (float)+2.1f;
273                 break;
274                 
275         default:        /* ID_OB and everything else */
276                 cur->xmin= (float)G.scene->r.sfra;
277                 cur->xmax= (float)G.scene->r.efra;
278                 cur->ymin= -5.0f;
279                 cur->ymax= +5.0f;
280                 break;
281         }
282 }
283
284 /* create a new IPO block (allocates the block) */
285 Ipo *add_ipo (char name[], int blocktype)
286 {
287         Ipo *ipo;
288         
289         ipo= alloc_libblock(&G.main->ipo, ID_IP, name);
290         ipo->blocktype= blocktype;
291         ipo_default_v2d_cur(blocktype, &ipo->cur);
292
293         return ipo;
294 }
295
296 /* ---------------------- Copy --------------------------- */
297
298 /* duplicate an IPO block and all its data  */
299 Ipo *copy_ipo (Ipo *src)
300 {
301         Ipo *dst;
302         IpoCurve *icu;
303         
304         if (src == NULL) 
305                 return NULL;
306         
307         dst= copy_libblock(src);
308         BLI_duplicatelist(&dst->curve, &src->curve);
309
310         for (icu= src->curve.first; icu; icu= icu->next) {
311                 icu->bezt= MEM_dupallocN(icu->bezt);
312                 
313                 if (icu->driver) 
314                         icu->driver= MEM_dupallocN(icu->driver);
315         }
316         
317         return dst;
318 }
319
320 /* ---------------------- Relink --------------------------- */
321
322 /* uses id->newid to match pointers with other copied data 
323  *      - called after single-user or other such
324  */
325 void ipo_idnew (Ipo *ipo)
326 {
327         if (ipo) {
328                 IpoCurve *icu;
329                 
330                 for (icu= ipo->curve.first; icu; icu= icu->next) {
331                         if (icu->driver)
332                                 ID_NEW(icu->driver->ob);
333                 }
334         }
335 }
336
337 /* --------------------- Find + Check ----------------------- */
338
339 /* find the IPO-curve within a given IPO-block with the adrcode of interest */
340 IpoCurve *find_ipocurve (Ipo *ipo, int adrcode)
341 {
342         if (ipo) {
343                 IpoCurve *icu;
344                 
345                 for (icu= ipo->curve.first; icu; icu= icu->next) {
346                         if (icu->adrcode == adrcode) 
347                                 return icu;
348                 }
349         }
350         return NULL;
351 }
352
353 /* return whether the given IPO block has a IPO-curve with the given adrcode */
354 short has_ipo_code(Ipo *ipo, int adrcode)
355 {
356         /* return success of faliure from trying to find such an IPO-curve */
357         return (find_ipocurve(ipo, adrcode) != NULL);
358 }
359
360 /* ---------------------- Make Local --------------------------- */
361
362
363 /* make the given IPO local (for Objects)
364  * - only lib users: do nothing
365  * - only local users: set flag
366  * - mixed: make copy
367  */
368 void make_local_obipo (Ipo *src)
369 {
370         Object *ob;
371         Ipo *dst;
372         int local=0, lib=0;
373         
374         /* check if only local and/or lib */
375         for (ob= G.main->object.first; ob; ob= ob->id.next) {
376                 if (ob->ipo == src) {
377                         if (ob->id.lib) lib= 1;
378                         else local= 1;
379                 }
380         }
381         
382         /* only local - set flag */
383         if (local && lib==0) {
384                 src->id.lib= 0;
385                 src->id.flag= LIB_LOCAL;
386                 new_id(0, (ID *)src, 0);
387         }
388         /* mixed: make copy */
389         else if (local && lib) {
390                 dst= copy_ipo(src);
391                 dst->id.us= 0;
392                 
393                 for (ob= G.main->object.first; ob; ob= ob->id.next) {
394                         if (ob->ipo == src) {
395                                 if (ob->id.lib == NULL) {
396                                         ob->ipo= dst;
397                                         dst->id.us++;
398                                         src->id.us--;
399                                 }
400                         }
401                 }
402         }
403 }
404
405 /* make the given IPO local (for Materials)
406  * - only lib users: do nothing
407  * - only local users: set flag
408  * - mixed: make copy
409  */
410 void make_local_matipo (Ipo *src)
411 {
412         Material *ma;
413         Ipo *dst;
414         int local=0, lib=0;
415         
416         /* check if only local and/or lib */
417         for (ma= G.main->mat.first; ma; ma= ma->id.next) {
418                 if (ma->ipo == src) {
419                         if (ma->id.lib) lib= 1;
420                         else local= 1;
421                 }
422         }
423         
424         /* only local - set flag */
425         if (local && lib==0) {
426                 src->id.lib= 0;
427                 src->id.flag= LIB_LOCAL;
428                 new_id(0, (ID *)src, 0);
429         }
430         /* mixed: make copy */
431         else if (local && lib) {
432                 dst= copy_ipo(src);
433                 dst->id.us= 0;
434                 
435                 for (ma= G.main->mat.first; ma; ma= ma->id.next) {
436                         if (ma->ipo == src) {
437                                 if (ma->id.lib == NULL) {
438                                         ma->ipo= dst;
439                                         dst->id.us++;
440                                         src->id.us--;
441                                 }
442                         }
443                 }
444         }
445 }
446
447 /* make the given IPO local (for ShapeKeys)
448  * - only lib users: do nothing
449  * - only local users: set flag
450  * - mixed: make copy
451  */
452 void make_local_keyipo (Ipo *src)
453 {
454         Key *key;
455         Ipo *dst;
456         int local=0, lib=0;
457         
458         /* check if only local and/or lib */
459         for (key= G.main->key.first; key; key= key->id.next) {
460                 if (key->ipo == src) {
461                         if (key->id.lib) lib= 1;
462                         else local= 1;
463                 }
464         }
465         
466         /* only local - set flag */
467         if (local && lib==0) {
468                 src->id.lib= 0;
469                 src->id.flag= LIB_LOCAL;
470                 new_id(0, (ID *)src, 0);
471         }
472         /* mixed: make copy */
473         else if (local && lib) {
474                 dst= copy_ipo(src);
475                 dst->id.us= 0;
476                 
477                 for (key= G.main->key.first; key; key= key->id.next) {
478                         if (key->ipo == src) {
479                                 if (key->id.lib == NULL) {
480                                         key->ipo= dst;
481                                         dst->id.us++;
482                                         src->id.us--;
483                                 }
484                         }
485                 }
486         }
487 }
488
489
490 /* generic call to make IPO's local */
491 void make_local_ipo (Ipo *ipo)
492 {
493         /* can't touch lib-linked data */
494         if (ipo->id.lib == NULL) 
495                 return;
496                 
497         /* with only one user, just set local flag */
498         if (ipo->id.us == 1) {
499                 ipo->id.lib= 0;
500                 ipo->id.flag= LIB_LOCAL;
501                 new_id(0, (ID *)ipo, 0);
502                 return;
503         }
504         
505         /* when more than 1 user, can only make local for certain blocktypes */
506         switch (ipo->blocktype) {
507                 case ID_OB:
508                         make_local_obipo(ipo);
509                         break;
510                 case ID_MA:
511                         make_local_matipo(ipo);
512                         break;
513                 case ID_KE:
514                         make_local_keyipo(ipo);
515                         break;
516         }
517 }
518
519 /* ***************************** Keyframe Column Tools ********************************* */
520
521 /* add a BezTriple to a column */
522 void add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
523 {
524         CfraElem *ce, *cen;
525         
526         for (ce= lb->first; ce; ce= ce->next) {
527                 /* double key? */
528                 if (ce->cfra == bezt->vec[1][0]) {
529                         if (bezt->f2 & SELECT) ce->sel= bezt->f2;
530                         return;
531                 }
532                 /* should key be inserted before this column? */
533                 else if (ce->cfra > bezt->vec[1][0]) break;
534         }
535         
536         /* create a new column */
537         cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); 
538         if (ce) BLI_insertlinkbefore(lb, ce, cen);
539         else BLI_addtail(lb, cen);
540
541         cen->cfra= bezt->vec[1][0];
542         cen->sel= bezt->f2;
543 }
544
545 /* make a list of keyframe 'columns' in an IPO block */
546 void make_cfra_list (Ipo *ipo, ListBase *elems)
547 {
548         IpoCurve *icu;
549         BezTriple *bezt;
550         int a;
551         
552         for (icu= ipo->curve.first; icu; icu= icu->next) {
553                 if (icu->flag & IPO_VISIBLE) {
554                         /* ... removed old checks for adrcode types from here ...
555                          *      - (was this used for IpoKeys in the past?)
556                          */
557                         
558                         bezt= icu->bezt;
559                         if (bezt) {
560                                 for (a=0; a < icu->totvert; a++, bezt++) {
561                                         add_to_cfra_elem(elems, bezt);
562                                 }
563                         }
564                 }
565         }
566 }
567
568 /* ***************************** Timing Stuff ********************************* */
569
570 /* This (evil) function is needed to cope with two legacy Blender rendering features
571  * mblur (motion blur that renders 'subframes' and blurs them together), and fields 
572  * rendering. Thus, the use of ugly globals from object.c
573  */
574 // BAD... EVIL... JUJU...!!!!
575 float frame_to_float (int cfra)         /* see also bsystem_time in object.c */
576 {
577         extern float bluroffs;  /* bad stuff borrowed from object.c */
578         extern float fieldoffs;
579         float ctime;
580         
581         ctime= (float)cfra;
582         ctime+= bluroffs+fieldoffs;
583         ctime*= G.scene->r.framelen;
584         
585         return ctime;
586 }
587
588 /* Calculate the extents of IPO block's keyframes */
589 void calc_ipo_range (Ipo *ipo, float *start, float *end)
590 {
591         IpoCurve *icu;
592         float min=999999999.0f, max=-999999999.0f;
593         short foundvert=0;
594
595         if (ipo) {
596                 for (icu=ipo->curve.first; icu; icu=icu->next) {
597                         if (icu->totvert) {
598                                 min= MIN2(min, icu->bezt[0].vec[1][0]);
599                                 max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
600                                 foundvert=1;
601                         }
602                 }
603         }       
604         
605         /* minimum length is 1 frame */
606         if (foundvert) {
607                 if (min == max) max += 1.0f;
608                 *start= min;
609                 *end= max;
610         }
611         else {
612                 *start= 0.0f;
613                 *end= 1.0f;
614         }
615 }
616
617 /* ***************************** IPO Curve Sanity ********************************* */
618 /* The functions here are used in various parts of Blender, usually after some editing
619  * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
620  * that the handles are correctly 
621  */
622
623 /* This function recalculates the handles of an IPO-Curve 
624  * If the BezTriples have been rearranged, sort them first before using this.
625  */
626 void calchandles_ipocurve (IpoCurve *icu)
627 {
628         BezTriple *bezt, *prev, *next;
629         int a= icu->totvert;
630
631         /* Error checking:
632          *      - need at least two points
633          *      - need bezier keys
634          *      - only bezier-interpolation has handles (for now)
635          */
636         if (ELEM(NULL, icu, icu->bezt) || (a < 2) || ELEM(icu->ipo, IPO_CONST, IPO_LIN)) 
637                 return;
638         
639         /* get initial pointers */
640         bezt= icu->bezt;
641         prev= NULL;
642         next= (bezt + 1);
643         
644         /* loop over all beztriples, adjusting handles */
645         while (a--) {
646                 /* clamp timing of handles to be on either side of beztriple */
647                 if (bezt->vec[0][0] > bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
648                 if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
649                 
650                 /* calculate autohandles */
651                 if (icu->flag & IPO_AUTO_HORIZ) 
652                         calchandleNurb(bezt, prev, next, 2);    /* 2==special autohandle && keep extrema horizontal */
653                 else
654                         calchandleNurb(bezt, prev, next, 1);    /* 1==special autohandle */
655                 
656                 /* for automatic ease in and out */
657                 if ((bezt->h1==HD_AUTO) && (bezt->h2==HD_AUTO)) {
658                         /* only do this on first or last beztriple */
659                         if ((a==0) || (a==icu->totvert-1)) {
660                                 /* set both handles to have same horizontal value as keyframe */
661                                 if (icu->extrap==IPO_HORIZ) {
662                                         bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
663                                 }
664                         }
665                 }
666                 
667                 /* advance pointers for next iteration */
668                 prev= bezt;
669                 if (a == 1) next= NULL;
670                 else next++;
671                 bezt++;
672         }
673 }
674
675 /* Use when IPO-Curve with handles has changed
676  * It treats all BezTriples with the following rules:
677  *  - PHASE 1: do types have to be altered?
678  *              -> Auto handles: become aligned when selection status is NOT(000 || 111)
679  *              -> Vector handles: become 'nothing' when (one half selected AND other not)
680  *  - PHASE 2: recalculate handles
681 */
682 void testhandles_ipocurve (IpoCurve *icu)
683 {
684         BezTriple *bezt;
685         int a;
686
687         /* only beztriples have handles (bpoints don't though) */
688         if (ELEM(NULL, icu, icu->bezt))
689                 return;
690         
691         /* loop over beztriples */
692         for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
693                 short flag= 0;
694                 
695                 /* flag is initialised as selection status
696                  * of beztriple control-points (labelled 0,1,2)
697                  */
698                 if (bezt->f1 & SELECT) flag |= (1<<0); // == 1
699                 if (bezt->f2 & SELECT) flag |= (1<<1); // == 2
700                 if (bezt->f3 & SELECT) flag |= (1<<2); // == 4
701                 
702                 /* one or two handles selected only */
703                 if (ELEM(flag, 0, 7)==0) {
704                         /* auto handles become aligned */
705                         if (bezt->h1==HD_AUTO)
706                                 bezt->h1= HD_ALIGN;
707                         if(bezt->h2==HD_AUTO)
708                                 bezt->h2= HD_ALIGN;
709                         
710                         /* vector handles become 'free' when only one half selected */
711                         if(bezt->h1==HD_VECT) {
712                                 /* only left half (1 or 2 or 1+2) */
713                                 if (flag < 4) 
714                                         bezt->h1= 0;
715                         }
716                         if(bezt->h2==HD_VECT) {
717                                 /* only right half (4 or 2+4) */
718                                 if (flag > 3) 
719                                         bezt->h2= 0;
720                         }
721                 }
722         }
723
724         /* recalculate handles */
725         calchandles_ipocurve(icu);
726 }
727
728 /* This function sorts BezTriples so that they are arranged in chronological order,
729  * as tools working on IPO-Curves expect that the BezTriples are in order.
730  */
731 void sort_time_ipocurve(IpoCurve *icu)
732 {
733         short ok= 1;
734         
735         /* keep adjusting order of beztriples until nothing moves (bubble-sort) */
736         while (ok) {
737                 ok= 0;
738                 
739                 /* currently, will only be needed when there are beztriples */
740                 if (icu->bezt) {
741                         BezTriple *bezt;
742                         int a;
743                         
744                         /* loop over ALL points to adjust position in array and recalculate handles */
745                         for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
746                                 /* check if thee's a next beztriple which we could try to swap with current */
747                                 if (a < (icu->totvert-1)) {
748                                         /* swap if one is after the other (and indicate that order has changed) */
749                                         if (bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
750                                                 SWAP(BezTriple, *bezt, *(bezt+1));
751                                                 ok= 1;
752                                         }
753                                         
754                                         /* if either one of both of the points exceeds crosses over the keyframe time... */
755                                         if ( (bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0]) ) {
756                                                 /* swap handles if they have switched sides for some reason */
757                                                 SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
758                                                 SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
759                                         }
760                                         else {
761                                                 /* clamp handles */
762                                                 if (bezt->vec[0][0] > bezt->vec[1][0]) 
763                                                         bezt->vec[0][0]= bezt->vec[1][0];
764                                                 if (bezt->vec[2][0] < bezt->vec[1][0]) 
765                                                         bezt->vec[2][0]= bezt->vec[1][0];
766                                         }
767                                 }
768                         }
769                 }
770         }
771 }
772
773 /* This function tests if any BezTriples are out of order, thus requiring a sort */
774 int test_time_ipocurve (IpoCurve *icu)
775 {
776         int a;
777         
778         /* currently, only need to test beztriples */
779         if (icu->bezt) {
780                 BezTriple *bezt;
781                 
782                 /* loop through all beztriples, stopping when one exceeds the one after it */
783                 for (a=0, bezt= icu->bezt; a < (icu->totvert - 1); a++, bezt++) {
784                         if (bezt->vec[1][0] > (bezt+1)->vec[1][0])
785                                 return 1;
786                 }
787         }
788         
789         /* none need any swapping */
790         return 0;
791 }
792
793 /* --------- */
794
795 /* The total length of the handles is not allowed to be more
796  * than the horizontal distance between (v1-v4).
797  * This is to prevent curve loops.
798 */
799 void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
800 {
801         float h1[2], h2[2], len1, len2, len, fac;
802         
803         /* calculate handle deltas */
804         h1[0]= v1[0]-v2[0];
805         h1[1]= v1[1]-v2[1];
806         h2[0]= v4[0]-v3[0];
807         h2[1]= v4[1]-v3[1];
808         
809         /* calculate distances: 
810          *      - len   = span of time between keyframes 
811          *      - len1  = length of handle of start key
812          *      - len2  = length of handle of end key
813          */
814         len= v4[0]- v1[0];
815         len1= (float)fabs(h1[0]);
816         len2= (float)fabs(h2[0]);
817         
818         /* if the handles have no length, no need to do any corrections */
819         if ((len1+len2) == 0.0) 
820                 return;
821                 
822         /* the two handles cross over each other, so force them
823          * apart using the proportion they overlap 
824          */
825         if ((len1+len2) > len) {
826                 fac= len/(len1+len2);
827                 
828                 v2[0]= (v1[0]-fac*h1[0]);
829                 v2[1]= (v1[1]-fac*h1[1]);
830                 
831                 v3[0]= (v4[0]-fac*h2[0]);
832                 v3[1]= (v4[1]-fac*h2[1]);
833         }
834 }
835
836 /* This function sets the interpolation mode for an entire Ipo-Curve. 
837  * It is primarily used for patching old files, but is also used in the interface
838  * to make sure that all segments of the curve use the same interpolation.
839  */
840 void set_interpolation_ipocurve (IpoCurve *icu, short ipo)
841 {
842         BezTriple *bezt;
843         int a;
844         
845         /* validate arguments */
846         if (icu == NULL) return;
847         if (ELEM3(ipo, IPO_CONST, IPO_LIN, IPO_BEZ)==0) return;
848
849         /* set interpolation mode for whole curve */
850         icu->ipo= ipo;
851         
852         /* set interpolation mode of all beztriples */
853         for (a=0, bezt=icu->bezt; a<icu->totvert; a++, bezt++)
854                 bezt->ipo= ipo;
855 }
856
857 /* ***************************** Curve Calculations ********************************* */
858
859 /* find root/zero */
860 int findzero (float x, float q0, float q1, float q2, float q3, float *o)
861 {
862         double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
863         int nr= 0;
864
865         c0= q0 - x;
866         c1= 3 * (q1 - q0);
867         c2= 3 * (q0 - 2*q1 + q2);
868         c3= q3 - q0 + 3 * (q1 - q2);
869         
870         if (c3 != 0.0) {
871                 a= c2/c3;
872                 b= c1/c3;
873                 c= c0/c3;
874                 a= a/3;
875                 
876                 p= b/3 - a*a;
877                 q= (2*a*a*a - a*b + c) / 2;
878                 d= q*q + p*p*p;
879                 
880                 if (d > 0.0) {
881                         t= sqrt(d);
882                         o[0]= (float)(Sqrt3d(-q+t) + Sqrt3d(-q-t) - a);
883                         
884                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
885                         else return 0;
886                 }
887                 else if (d == 0.0) {
888                         t= Sqrt3d(-q);
889                         o[0]= (float)(2*t - a);
890                         
891                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
892                         o[nr]= (float)(-t-a);
893                         
894                         if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
895                         else return nr;
896                 }
897                 else {
898                         phi= acos(-q / sqrt(-(p*p*p)));
899                         t= sqrt(-p);
900                         p= cos(phi/3);
901                         q= sqrt(3 - 3*p*p);
902                         o[0]= (float)(2*t*p - a);
903                         
904                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
905                         o[nr]= (float)(-t * (p + q) - a);
906                         
907                         if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) nr++;
908                         o[nr]= (float)(-t * (p - q) - a);
909                         
910                         if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
911                         else return nr;
912                 }
913         }
914         else {
915                 a=c2;
916                 b=c1;
917                 c=c0;
918                 
919                 if (a != 0.0) {
920                         // discriminant
921                         p= b*b - 4*a*c;
922                         
923                         if (p > 0) {
924                                 p= sqrt(p);
925                                 o[0]= (float)((-b-p) / (2 * a));
926                                 
927                                 if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
928                                 o[nr]= (float)((-b+p)/(2*a));
929                                 
930                                 if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
931                                 else return nr;
932                         }
933                         else if (p == 0) {
934                                 o[0]= (float)(-b / (2 * a));
935                                 if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
936                                 else return 0;
937                         }
938                 }
939                 else if (b != 0.0) {
940                         o[0]= (float)(-c/b);
941                         
942                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
943                         else return 0;
944                 }
945                 else if (c == 0.0) {
946                         o[0]= 0.0;
947                         return 1;
948                 }
949                 
950                 return 0;       
951         }
952 }
953
954 void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
955 {
956         float t, c0, c1, c2, c3;
957         int a;
958
959         c0= f1;
960         c1= 3.0f * (f2 - f1);
961         c2= 3.0f * (f1 - 2.0f*f2 + f3);
962         c3= f4 - f1 + 3.0f * (f2 - f3);
963         
964         for (a=0; a < b; a++) {
965                 t= o[a];
966                 o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
967         }
968 }
969
970 void berekenx (float *f, float *o, int b)
971 {
972         float t, c0, c1, c2, c3;
973         int a;
974
975         c0= f[0];
976         c1= 3 * (f[3] - f[0]);
977         c2= 3 * (f[0] - 2*f[3] + f[6]);
978         c3= f[9] - f[0] + 3 * (f[3] - f[6]);
979         
980         for (a=0; a < b; a++) {
981                 t= o[a];
982                 o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
983         }
984 }
985
986 /* ***************************** IPO - Calculations ********************************* */
987
988 /* ---------------------- Curve Evaluation --------------------------- */
989
990 /* helper function for evaluating drivers: 
991  *      - we need the local transform = current transform - (parent transform + bone transform)
992  *      - (local transform is on action channel level)
993  */
994 static void posechannel_get_local_transform (bPoseChannel *pchan, float loc[], float eul[], float size[])
995 {
996         float parmat[4][4], offs_bone[4][4], imat[4][4];
997         float diff_mat[4][4];
998         
999         /* get first the parent + bone transform in parmat */
1000         if (pchan->parent) {
1001                 /* bone transform itself */
1002                 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
1003                 
1004                 /* The bone's root offset (is in the parent's coordinate system) */
1005                 VECCOPY(offs_bone[3], pchan->bone->head);
1006                 
1007                 /* Get the length translation of parent (length along y axis) */
1008                 offs_bone[3][1]+= pchan->parent->bone->length;
1009                 
1010                 Mat4MulSerie(parmat, pchan->parent->pose_mat, offs_bone, NULL, NULL, NULL, NULL, NULL, NULL);
1011                 
1012                 /* invert it */
1013                 Mat4Invert(imat, parmat);
1014         }
1015         else {
1016                 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
1017                 VECCOPY(offs_bone[3], pchan->bone->head);
1018                 
1019                 /* invert it */
1020                 Mat4Invert(imat, offs_bone);
1021         }
1022         
1023         /* difference: current transform - (parent transform + bone transform)  */
1024         Mat4MulMat4(diff_mat, pchan->pose_mat, imat);
1025
1026         /* extract relevant components */
1027         if (loc)
1028                 VECCOPY(loc, diff_mat[3]);
1029         if (eul)
1030                 Mat4ToEul(diff_mat, eul);
1031         if (size)
1032                 Mat4ToSize(diff_mat, size);
1033 }
1034
1035 /* evaluate an IPO-driver to get a 'time' value to use instead of "ipotime"
1036  *      - "ipotime" is the frame at which IPO-curve is being evaluated
1037  *      - has to return a float value 
1038  */
1039 static float eval_driver (IpoDriver *driver, float ipotime)
1040 {
1041 #ifndef DISABLE_PYTHON
1042         /* currently, drivers are either PyDrivers (evaluating a PyExpression, or Object/Pose-Channel transforms) */
1043         if (driver->type == IPO_DRIVER_TYPE_PYTHON) {
1044                 /* check for empty or invalid expression */
1045                 if ( (driver->name[0] == '\0') ||
1046                          (driver->flag & IPO_DRIVER_FLAG_INVALID) )
1047                 {
1048                         return 0.0f;
1049                 }
1050                 
1051                 /* this evaluates the expression using Python,and returns its result:
1052                  *      - on errors it reports, then returns 0.0f
1053                  */
1054                 return BPY_pydriver_eval(driver);
1055         }
1056         else
1057 #endif /* DISABLE_PYTHON */
1058         {
1059                 Object *ob= driver->ob;
1060                 
1061                 /* must have an object to evaluate */
1062                 if (ob == NULL) 
1063                         return 0.0f;
1064                         
1065                 /* if a proxy, use the proxy source*/
1066                 if (ob->proxy_from)
1067                         ob= ob->proxy_from;
1068                 
1069                 /* use given object as driver */
1070                 if (driver->blocktype == ID_OB) {
1071                         /* depsgraph failure: ob ipos are calculated in where_is_object, this might get called too late */
1072                         if ((ob->ipo) && (ob->ctime != ipotime)) {
1073                                 /* calculate the value of relevant channel on the Object, but do not write the value
1074                                  * calculated on to the Object but onto "ipotime" instead
1075                                  */
1076                                 calc_ipo_spec(ob->ipo, driver->adrcode, &ipotime);
1077                                 return ipotime;
1078                         }
1079                         
1080                         /* return the value of the relevant channel */
1081                         switch (driver->adrcode) {
1082                         case OB_LOC_X:
1083                                 return ob->loc[0];
1084                         case OB_LOC_Y:
1085                                 return ob->loc[1];
1086                         case OB_LOC_Z:
1087                                 return ob->loc[2];
1088                         case OB_ROT_X:  /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
1089                                 return (float)( ob->rot[0]/(M_PI_2/9.0) );
1090                         case OB_ROT_Y:  /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
1091                                 return (float)( ob->rot[1]/(M_PI_2/9.0) );
1092                         case OB_ROT_Z:  /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
1093                                 return (float)( ob->rot[2]/(M_PI_2/9.0) );
1094                         case OB_SIZE_X:
1095                                 return ob->size[0];
1096                         case OB_SIZE_Y:
1097                                 return ob->size[1];
1098                         case OB_SIZE_Z:
1099                                 return ob->size[2];
1100                         }
1101                 }
1102                 
1103                 /* use given pose-channel as driver */
1104                 else {  /* ID_AR */
1105                         bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
1106                         
1107                         /* must have at least 1 bone to use */
1108                         if (pchan && pchan->bone) {
1109                                 /* rotation difference is not a simple driver (i.e. value drives value), but the angle between 2 bones is driving stuff... 
1110                                  *      - the name of the second pchan is also stored in driver->name, but packed after the other one by DRIVER_NAME_OFFS chars
1111                                  */
1112                                 if (driver->adrcode == OB_ROT_DIFF) {
1113                                         bPoseChannel *pchan2= get_pose_channel(ob->pose, driver->name+DRIVER_NAME_OFFS);
1114                                         
1115                                         if (pchan2 && pchan2->bone) {
1116                                                 float q1[4], q2[4], quat[4], angle;
1117                                                 
1118                                                 Mat4ToQuat(pchan->pose_mat, q1);
1119                                                 Mat4ToQuat(pchan2->pose_mat, q2);
1120                                                 
1121                                                 QuatInv(q1);
1122                                                 QuatMul(quat, q1, q2);
1123                                                 angle = 2.0f * (saacos(quat[0]));
1124                                                 angle= ABS(angle);
1125                                                 
1126                                                 return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
1127                                         }
1128                                 }
1129                                 
1130                                 /* standard driver */
1131                                 else {
1132                                         float loc[3], eul[3], size[3];
1133                                         
1134                                         /* retrieve local transforms to return 
1135                                          *      - we use eulers here NOT quats, so that Objects can be driven by bones easily
1136                                          *        also, this way is more understandable for users
1137                                          */
1138                                         posechannel_get_local_transform(pchan, loc, eul, size);
1139                                         
1140                                         switch (driver->adrcode) {
1141                                         case OB_LOC_X:
1142                                                 return loc[0];
1143                                         case OB_LOC_Y:
1144                                                 return loc[1];
1145                                         case OB_LOC_Z:
1146                                                 return loc[2];
1147                                         case OB_ROT_X: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
1148                                                 return (float)( eul[0]/(M_PI_2/9.0) );
1149                                         case OB_ROT_Y: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
1150                                                 return (float)( eul[1]/(M_PI_2/9.0) );
1151                                         case OB_ROT_Z: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
1152                                                 return (float)( eul[2]/(M_PI_2/9.0) );
1153                                         case OB_SIZE_X:
1154                                                 return size[0];
1155                                         case OB_SIZE_Y:
1156                                                 return size[1];
1157                                         case OB_SIZE_Z:
1158                                                 return size[2];
1159                                         }
1160                                 }
1161                         }
1162                 }
1163         }       
1164         
1165         /* return 0.0f, as couldn't find relevant data to use */
1166         return 0.0f;
1167 }
1168
1169 /* evaluate and return the value of the given IPO-curve at the specified frame ("evaltime") */
1170 float eval_icu (IpoCurve *icu, float evaltime) 
1171 {
1172         float cvalue = 0.0f;
1173         
1174         /* if there is a driver, evaluate it to find value to use as "evaltime" 
1175          *      - this value will also be returned as the value of the 'curve', if there are no keyframes
1176          */
1177         if (icu->driver) {
1178                 /* ipotime now serves as input for the curve */
1179                 evaltime= cvalue= eval_driver(icu->driver, evaltime);
1180         }
1181         
1182         /* there are keyframes (in the form of BezTriples) which can be interpolated between */
1183         if (icu->bezt) {
1184                 /* get pointers */
1185                 BezTriple *bezt, *prevbezt, *lastbezt;
1186                 float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
1187                 float cycdx, cycdy, ofs, cycyofs= 0.0f;
1188                 int a, b;
1189                 
1190                 /* get pointers */
1191                 a= icu->totvert-1;
1192                 prevbezt= icu->bezt;
1193                 bezt= prevbezt+1;
1194                 lastbezt= prevbezt + a;
1195                 
1196                 /* extrapolation mode is 'cyclic' - find relative place within a cycle */
1197                 if (icu->extrap & IPO_CYCL) {
1198                         /* ofs is start frame of cycle */
1199                         ofs= prevbezt->vec[1][0];
1200                         
1201                         /* calculate period and amplitude (total height) of a cycle */
1202                         cycdx= lastbezt->vec[1][0] - prevbezt->vec[1][0];
1203                         cycdy= lastbezt->vec[1][1] - prevbezt->vec[1][1];
1204                         
1205                         /* cycle occurs over some period of time (cycdx should be positive all the time) */
1206                         if (cycdx) {
1207                                 /* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle
1208                                  *      - IPO_CYCLX = (IPO_CYCL + IPO_DIR)
1209                                  */
1210                                 if (icu->extrap & IPO_DIR) {
1211                                         cycyofs = (float)floor((evaltime - ofs) / cycdx);
1212                                         cycyofs *= cycdy;
1213                                 }
1214                                 
1215                                 /* calculate where in the cycle we are (overwrite evaltime to reflect this) */
1216                                 evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
1217                                 if (evaltime < ofs) evaltime += cycdx;
1218                         }
1219                 }
1220                 
1221                 /* evaluation time at or past endpoints? */
1222                 if (prevbezt->vec[1][0] >= evaltime) {
1223                         /* before or on first keyframe */
1224                         if ((icu->extrap & IPO_DIR) && (prevbezt->ipo != IPO_CONST)) {
1225                                 /* linear or bezier interpolation */
1226                                 if (prevbezt->ipo==IPO_LIN) {
1227                                         /* Use the next center point instead of our own handle for
1228                                          * linear interpolated extrapolate 
1229                                          */
1230                                         if (icu->totvert == 1) 
1231                                                 cvalue= prevbezt->vec[1][1];
1232                                         else {
1233                                                 bezt = prevbezt+1;
1234                                                 dx= prevbezt->vec[1][0] - evaltime;
1235                                                 fac= bezt->vec[1][0] - prevbezt->vec[1][0];
1236                                                 
1237                                                 /* prevent division by zero */
1238                                                 if (fac) {
1239                                                         fac= (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
1240                                                         cvalue= prevbezt->vec[1][1] - (fac * dx);
1241                                                 }
1242                                                 else 
1243                                                         cvalue= prevbezt->vec[1][1];
1244                                         }
1245                                 } 
1246                                 else {
1247                                         /* Use the first handle (earlier) of first BezTriple to calculate the
1248                                          * gradient and thus the value of the curve at evaltime
1249                                          */
1250                                         dx= prevbezt->vec[1][0] - evaltime;
1251                                         fac= prevbezt->vec[1][0] - prevbezt->vec[0][0];
1252                                         
1253                                         /* prevent division by zero */
1254                                         if (fac) {
1255                                                 fac= (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
1256                                                 cvalue= prevbezt->vec[1][1] - (fac * dx);
1257                                         }
1258                                         else 
1259                                                 cvalue= prevbezt->vec[1][1];
1260                                 }
1261                         }
1262                         else {
1263                                 /* constant (IPO_HORIZ) extrapolation or constant interpolation, 
1264                                  * so just extend first keyframe's value 
1265                                  */
1266                                 cvalue= prevbezt->vec[1][1];
1267                         }
1268                 }
1269                 else if (lastbezt->vec[1][0] <= evaltime) {
1270                         /* after or on last keyframe */
1271                         if( (icu->extrap & IPO_DIR) && (lastbezt->ipo != IPO_CONST)) {
1272                                 /* linear or bezier interpolation */
1273                                 if (lastbezt->ipo==IPO_LIN) {
1274                                         /* Use the next center point instead of our own handle for
1275                                          * linear interpolated extrapolate 
1276                                          */
1277                                         if (icu->totvert == 1) 
1278                                                 cvalue= lastbezt->vec[1][1];
1279                                         else {
1280                                                 prevbezt = lastbezt - 1;
1281                                                 dx= evaltime - lastbezt->vec[1][0];
1282                                                 fac= lastbezt->vec[1][0] - prevbezt->vec[1][0];
1283                                                 
1284                                                 /* prevent division by zero */
1285                                                 if (fac) {
1286                                                         fac= (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
1287                                                         cvalue= lastbezt->vec[1][1] + (fac * dx);
1288                                                 }
1289                                                 else 
1290                                                         cvalue= lastbezt->vec[1][1];
1291                                         }
1292                                 } 
1293                                 else {
1294                                         /* Use the gradient of the second handle (later) of last BezTriple to calculate the
1295                                          * gradient and thus the value of the curve at evaltime
1296                                          */
1297                                         dx= evaltime - lastbezt->vec[1][0];
1298                                         fac= lastbezt->vec[2][0] - lastbezt->vec[1][0];
1299                                         
1300                                         /* prevent division by zero */
1301                                         if (fac) {
1302                                                 fac= (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
1303                                                 cvalue= lastbezt->vec[1][1] + (fac * dx);
1304                                         }
1305                                         else 
1306                                                 cvalue= lastbezt->vec[1][1];
1307                                 }
1308                         }
1309                         else {
1310                                 /* constant (IPO_HORIZ) extrapolation or constant interpolation, 
1311                                  * so just extend last keyframe's value 
1312                                  */
1313                                 cvalue= lastbezt->vec[1][1];
1314                         }
1315                 }
1316                 else {
1317                         /* evaltime occurs somewhere in the middle of the curve */
1318                         for (a=0; prevbezt && bezt && (a < icu->totvert-1); a++, prevbezt=bezt, bezt++) {  
1319                                 /* evaltime occurs within the interval defined by these two keyframes */
1320                                 if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
1321                                         /* value depends on interpolation mode */
1322                                         if (prevbezt->ipo == IPO_CONST) {
1323                                                 /* constant (evaltime not relevant, so no interpolation needed) */
1324                                                 cvalue= prevbezt->vec[1][1];
1325                                         }
1326                                         else if (prevbezt->ipo == IPO_LIN) {
1327                                                 /* linear - interpolate between values of the two keyframes */
1328                                                 fac= bezt->vec[1][0] - prevbezt->vec[1][0];
1329                                                 
1330                                                 /* prevent division by zero */
1331                                                 if (fac) {
1332                                                         fac= (evaltime - prevbezt->vec[1][0]) / fac;
1333                                                         cvalue= prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
1334                                                 }
1335                                                 else
1336                                                         cvalue= prevbezt->vec[1][1];
1337                                         }
1338                                         else {
1339                                                 /* bezier interpolation */
1340                                                         /* v1,v2 are the first keyframe and its 2nd handle */
1341                                                 v1[0]= prevbezt->vec[1][0];
1342                                                 v1[1]= prevbezt->vec[1][1];
1343                                                 v2[0]= prevbezt->vec[2][0];
1344                                                 v2[1]= prevbezt->vec[2][1];
1345                                                         /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
1346                                                 v3[0]= bezt->vec[0][0];
1347                                                 v3[1]= bezt->vec[0][1];
1348                                                 v4[0]= bezt->vec[1][0];
1349                                                 v4[1]= bezt->vec[1][1];
1350                                                 
1351                                                 /* adjust handles so that they don't overlap (forming a loop) */
1352                                                 correct_bezpart(v1, v2, v3, v4);
1353                                                 
1354                                                 /* try to get a value for this position - if failure, try another set of points */
1355                                                 b= findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
1356                                                 if (b) {
1357                                                         berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
1358                                                         cvalue= opl[0];
1359                                                         break;
1360                                                 }
1361                                         }
1362                                 }
1363                         }
1364                 }
1365                 
1366                 /* apply y-offset (for 'cyclic extrapolation') to calculated value */
1367                 cvalue += cycyofs;
1368         }
1369         
1370         /* clamp evaluated value to lie within allowable value range for this channel */
1371         if (icu->ymin < icu->ymax) {
1372                 CLAMP(cvalue, icu->ymin, icu->ymax);
1373         }
1374         
1375         /* return evaluated value */
1376         return cvalue;
1377 }
1378
1379 /* ------------------- IPO-Block/Curve Calculation - General API ----------------------- */
1380
1381 /* calculate the value of the given IPO-curve at the current frame, and set its curval */
1382 void calc_icu (IpoCurve *icu, float ctime)
1383 {
1384         /* calculate and set curval (evaluates driver too) */
1385         icu->curval= eval_icu(icu, ctime);
1386 }
1387
1388 /* calculate for the current frame, all IPO-curves in IPO-block that can be evaluated 
1389  *      - icu->curval is set for all IPO-curves which are evaluated!
1390  */
1391 void calc_ipo (Ipo *ipo, float ctime)
1392 {
1393         IpoCurve *icu;
1394         
1395         /* if there is no IPO block to evaluate, or whole block is "muted" */
1396         if (ipo == NULL) return;
1397         if (ipo->muteipo) return;
1398         
1399         /* loop over all curves */
1400         for (icu= ipo->curve.first; icu; icu= icu->next) {
1401                 /* only evaluated curve if allowed to:
1402                  *      - Muted channels should not be evaluated as they shouldn't have any effect 
1403                  *              --> user explictly turned them off!
1404                  *      - Drivers should be evaluated at all updates
1405                  *              --> TODO Note: drivers should be separated from standard channels
1406                  *      - IPO_LOCK is not set, as it is set by some internal mechanisms to prevent
1407                  *              IPO-curve from overwriting data (currently only used for IPO-Record). 
1408                  */
1409                 if ((icu->driver) || (icu->flag & IPO_LOCK)==0) { 
1410                         if ((icu->flag & IPO_MUTE)==0)
1411                                 calc_icu(icu, ctime);
1412                 }
1413         }
1414 }
1415
1416 /* ------------------- IPO-Block/Curve Calculation - Special Hacks ----------------------- */
1417
1418 /* Calculate and return the value of the 'Time' Ipo-Curve from an Object,
1419  * OR return the current time if not found
1420  *      - used in object.c -> bsystem_time() 
1421  */
1422 float calc_ipo_time (Ipo *ipo, float ctime)
1423 {
1424         /* only Time IPO from Object IPO-blocks are relevant */
1425         if ((ipo) && (ipo->blocktype == ID_OB)) {
1426                 IpoCurve *icu= find_ipocurve(ipo, OB_TIME);
1427                 
1428                 /* only calculate (and set icu->curval) for time curve */
1429                 if (icu) {
1430                         calc_icu(icu, ctime);
1431                         return (10.0f * icu->curval);
1432                 }
1433         }
1434         
1435         /* no appropriate time-curve found */
1436         return ctime;
1437 }
1438
1439 /* Evaluate the specified channel in the given IPO block on the specified frame (ctime),
1440  * writing the value into that channel's icu->curval, but ALSO dumping it in ctime.
1441  *      - Returns success and modifies ctime! 
1442  */
1443 short calc_ipo_spec (Ipo *ipo, int adrcode, float *ctime)
1444 {
1445         IpoCurve *icu= find_ipocurve(ipo, adrcode);
1446         
1447         /* only evaluate if found */
1448         if (icu) {
1449                 /* only calculate if allowed to (not locked and not muted) 
1450                  *      - drivers not taken into account, because this may be called when calculating a driver
1451                  */
1452                 if ((icu->flag & (IPO_LOCK|IPO_MUTE))==0) 
1453                         calc_icu(icu, *ctime);
1454                 
1455                 /* value resulting from calculations is written into ctime! */
1456                 *ctime= icu->curval;
1457                 return 1;
1458         }
1459         
1460         /* couldn't evaluate */
1461         return 0;
1462 }
1463
1464 /* ***************************** IPO - DataAPI ********************************* */
1465
1466 /* --------------------- Flush/Execute IPO Values ----------------------------- */
1467
1468 /* Flush IpoCurve->curvals to the data they affect (defined by ID)
1469  *       - not for Actions or Constraints!  (those have their own special handling)
1470  */
1471 void execute_ipo (ID *id, Ipo *ipo)
1472 {
1473         IpoCurve *icu;
1474         void *poin;
1475         int type;
1476         
1477         /* don't do anything without an IPO block */
1478         if (ipo == NULL) 
1479                 return;
1480         
1481         /* loop over IPO Curves, getting pointer to var to affect, and write into that pointer */
1482         for (icu= ipo->curve.first; icu; icu= icu->next) {
1483                 poin= get_ipo_poin(id, icu, &type);
1484                 if (poin) write_ipo_poin(poin, type, icu->curval);
1485         }
1486 }
1487
1488 /* Flush Action-Channel IPO data to Pose Channel */
1489 void execute_action_ipo (bActionChannel *achan, bPoseChannel *pchan)
1490 {
1491         /* only do this if there's an Action Channel and Pose Channel to use */
1492         if (achan && achan->ipo && pchan) {
1493                 IpoCurve *icu;
1494                 
1495                 /* loop over IPO-curves, getting a pointer to pchan var to write to */
1496                 for (icu= achan->ipo->curve.first; icu; icu= icu->next) {
1497                         void *poin= get_pchan_ipo_poin(pchan, icu->adrcode);
1498                         
1499                         if (poin) {
1500                                 /* only euler-rotations are of type float-degree, all others are 'float' only */
1501                                 if (ELEM3(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))
1502                                         write_ipo_poin(poin, IPO_FLOAT_DEGR, icu->curval);
1503                                 else
1504                                         write_ipo_poin(poin, IPO_FLOAT, icu->curval);
1505                         }
1506                 }
1507         }
1508 }
1509
1510
1511 /* --------------------- Force Calculation + Flush IPO Values ----------------------------- */
1512
1513 /* Calculate values for given IPO block, then flush to all of block's users
1514  *       - for general usage 
1515  */
1516 void do_ipo (Ipo *ipo)
1517 {
1518         if (ipo) {
1519                 float ctime= frame_to_float(G.scene->r.cfra);
1520                 
1521                 /* calculate values, then flush to all users of this IPO block */
1522                 calc_ipo(ipo, ctime);
1523                 do_ipo_nocalc(ipo);
1524         }
1525 }
1526
1527 /* Calculate values for given Material's IPO block, then flush to given Material only */
1528 void do_mat_ipo (Material *ma)
1529 {
1530         float ctime;
1531         
1532         if (ELEM(NULL, ma, ma->ipo)) 
1533                 return;
1534         
1535         ctime= frame_to_float(G.scene->r.cfra);
1536         /* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */
1537         
1538         /* calculate values for current time, then flush values to given material only */
1539         calc_ipo(ma->ipo, ctime);
1540         execute_ipo((ID *)ma, ma->ipo);
1541 }
1542
1543 /* Calculate values for given Object's IPO block, then flush to given Object only
1544  *      - there's also some funky stuff that looks like it's for scene layers
1545  */
1546 void do_ob_ipo (Object *ob)
1547 {
1548         float ctime;
1549         unsigned int lay;
1550         
1551         if (ob->ipo == NULL) 
1552                 return;
1553         
1554         /* do not set ob->ctime here: for example when parent in invisible layer */
1555         ctime= bsystem_time(ob, (float) G.scene->r.cfra, 0.0);
1556         
1557         /* calculate values of */
1558         calc_ipo(ob->ipo, ctime);
1559         
1560         /* Patch: remember localview */
1561         lay= ob->lay & 0xFF000000;
1562         
1563         /* flush IPO values to this object only */
1564         execute_ipo((ID *)ob, ob->ipo);
1565         
1566         /* hack: for layer animation??? - is this what this is? (Aligorith, 28Sep2008) */
1567         ob->lay |= lay;
1568         if ((ob->id.name[2]=='S') && (ob->id.name[3]=='C') && (ob->id.name[4]=='E')) {
1569                 if (strcmp(G.scene->id.name+2, ob->id.name+6)==0) {
1570                         G.scene->lay= ob->lay;
1571                         //XXX copy_view3d_lock(0);
1572                         /* no redraw here! creates too many calls */
1573                 }
1574         }
1575 }
1576
1577 /* Only execute those IPO-Curves with drivers, on the current frame, for the given Object
1578  *      - TODO: Drivers should really be made separate from standard anim channels
1579  */
1580 void do_ob_ipodrivers (Object *ob, Ipo *ipo, float ctime)
1581 {
1582         IpoCurve *icu;
1583         void *poin;
1584         int type;
1585         
1586         for (icu= ipo->curve.first; icu; icu= icu->next) {
1587                 if (icu->driver) {
1588                         icu->curval= eval_icu(icu, ctime);
1589                         
1590                         poin= get_ipo_poin((ID *)ob, icu, &type);
1591                         if (poin) write_ipo_poin(poin, type, icu->curval);
1592                 }
1593         }
1594 }
1595
1596 /* Special variation to calculate IPO values for Sequence + perform other stuff */
1597 void do_seq_ipo (Sequence *seq, int cfra)
1598 {
1599         float ctime, div;
1600         
1601         /* seq_ipo has an exception: calc both fields immediately */
1602         if (seq->ipo) {
1603                 if ((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
1604                         ctime = frame_to_float(cfra);
1605                         div = 1.0;
1606                 } 
1607                 else {
1608                         ctime= frame_to_float(cfra - seq->startdisp);
1609                         div= (seq->enddisp - seq->startdisp) / 100.0f;
1610                         if (div == 0.0) return;
1611                 }
1612                 
1613                 /* 2nd field */
1614                 calc_ipo(seq->ipo, (ctime+0.5f)/div);
1615                 execute_ipo((ID *)seq, seq->ipo);
1616                 seq->facf1= seq->facf0;
1617                 
1618                 /* 1st field */
1619                 calc_ipo(seq->ipo, ctime/div);
1620                 execute_ipo((ID *)seq, seq->ipo);
1621         }
1622         else 
1623                 seq->facf1= seq->facf0= 1.0f;
1624 }
1625
1626 /* --------- */
1627
1628
1629 /* exception: it does calc for objects...
1630  * now find out why this routine was used anyway!
1631  */
1632 void do_ipo_nocalc (Ipo *ipo)
1633 {
1634         Object *ob;
1635         Material *ma;
1636         Tex *tex;
1637         World *wo;
1638         Lamp *la;
1639         Camera *ca;
1640         bSound *snd;
1641         
1642         if (ipo == NULL) 
1643                 return;
1644         
1645         /* only flush IPO values (without calculating first/again) on 
1646          * to the datablocks that use the given IPO block 
1647          */
1648         switch (ipo->blocktype) {
1649         case ID_OB:
1650                 for (ob= G.main->object.first; ob; ob= ob->id.next) {
1651                         if (ob->ipo == ipo) do_ob_ipo(ob);
1652                 }
1653                 break;
1654         case ID_MA:
1655                 for (ma= G.main->mat.first; ma; ma= ma->id.next) {
1656                         if (ma->ipo == ipo) execute_ipo((ID *)ma, ipo);
1657                 }
1658                 break;
1659         case ID_TE:
1660                 for (tex= G.main->tex.first; tex; tex= tex->id.next) {
1661                         if (tex->ipo == ipo) execute_ipo((ID *)tex, ipo);
1662                 }
1663                 break;
1664         case ID_WO:
1665                 for (wo= G.main->world.first; wo; wo= wo->id.next) {
1666                         if (wo->ipo == ipo) execute_ipo((ID *)wo, ipo);
1667                 }
1668                 break;
1669         case ID_LA:
1670                 for (la= G.main->lamp.first; la; la= la->id.next) {
1671                         if (la->ipo == ipo) execute_ipo((ID *)la, ipo);
1672                 }
1673                 break;
1674         case ID_CA:
1675                 for (ca= G.main->camera.first; ca; ca= ca->id.next) {
1676                         if (ca->ipo == ipo) execute_ipo((ID *)ca, ipo);
1677                 }
1678                 break;
1679         case ID_SO:
1680                 for (snd= G.main->sound.first; snd; snd= snd->id.next) {
1681                         if (snd->ipo == ipo) execute_ipo((ID *)snd, ipo);
1682                 }
1683                 break;
1684         }
1685 }
1686
1687 /* Executes IPO's for whole database on frame change, in a specified order,
1688  * with datablocks being calculated in alphabetical order
1689  *      - called on scene_update_for_newframe() only 
1690  */
1691 void do_all_data_ipos ()
1692 {
1693         Material *ma;
1694         Tex *tex;
1695         World *wo;
1696         Ipo *ipo;
1697         Lamp *la;
1698         Key *key;
1699         Camera *ca;
1700         bSound *snd;
1701         Sequence *seq;
1702         Editing *ed;
1703         Base *base;
1704         float ctime;
1705
1706         ctime= frame_to_float(G.scene->r.cfra);
1707         
1708         /* this exception cannot be depgraphed yet... what todo with objects in other layers?... */
1709         for (base= G.scene->base.first; base; base= base->next) {
1710                 Object *ob= base->object;
1711                 
1712                 /* only update layer when an ipo */
1713                 if (has_ipo_code(ob->ipo, OB_LAY)) {
1714                         do_ob_ipo(ob);
1715                         base->lay= ob->lay;
1716                 }
1717         }
1718         
1719         /* layers for the set...*/
1720         if (G.scene->set) {
1721                 for (base= G.scene->set->base.first; base; base= base->next) {
1722                         Object *ob= base->object;
1723                         
1724                         if (has_ipo_code(ob->ipo, OB_LAY)) {
1725                                 do_ob_ipo(ob);
1726                                 base->lay= ob->lay;
1727                         }
1728                 }
1729         }
1730         
1731         /* Calculate all IPO blocks in use, execept those for Objects */
1732         for (ipo= G.main->ipo.first; ipo; ipo= ipo->id.next) {
1733                 if ((ipo->id.us) && (ipo->blocktype != ID_OB)) {
1734                         calc_ipo(ipo, ctime);
1735                 }
1736         }
1737
1738         /* Texture Blocks */
1739         for (tex= G.main->tex.first; tex; tex= tex->id.next) {
1740                 if (tex->ipo) execute_ipo((ID *)tex, tex->ipo);
1741         }
1742         
1743         /* Material Blocks */
1744         for (ma= G.main->mat.first; ma; ma= ma->id.next) {
1745                 if (ma->ipo) execute_ipo((ID *)ma, ma->ipo);
1746         }
1747         
1748         /* World Blocks */
1749         for (wo= G.main->world.first; wo; wo= wo->id.next) {
1750                 if (wo->ipo) execute_ipo((ID *)wo, wo->ipo);
1751         }
1752         
1753         /* ShapeKey Blocks */
1754         for (key= G.main->key.first; key; key= key->id.next) {
1755                 if (key->ipo) execute_ipo((ID *)key, key->ipo);
1756         }
1757         
1758         /* Lamp Blocks */
1759         for (la= G.main->lamp.first; la; la= la->id.next) {
1760                 if (la->ipo) execute_ipo((ID *)la, la->ipo);
1761         }
1762         
1763         /* Camera Blocks */
1764         for (ca= G.main->camera.first; ca; ca= ca->id.next) {
1765                 if (ca->ipo) execute_ipo((ID *)ca, ca->ipo);
1766         }
1767         
1768         /* Sound Blocks (Old + Unused) */
1769         for (snd= G.main->sound.first; snd; snd= snd->id.next) {
1770                 if (snd->ipo) execute_ipo((ID *)snd, snd->ipo);
1771         }
1772
1773         /* Sequencer: process FAC Ipos used as volume envelopes */
1774         ed= G.scene->ed;
1775         if (ed) {
1776                 for (seq= ed->seqbasep->first; seq; seq= seq->next) {
1777                         if ( ((seq->type == SEQ_RAM_SOUND) || (seq->type == SEQ_HD_SOUND)) &&
1778                                  (seq->startdisp <= G.scene->r.cfra+2) && 
1779                              (seq->enddisp>G.scene->r.cfra) &&
1780                                  (seq->ipo) ) 
1781                         {
1782                                         do_seq_ipo(seq, G.scene->r.cfra);
1783                         }
1784                 }
1785         }
1786 }
1787
1788
1789 /* --------------------- Assorted ----------------------------- */ 
1790
1791 /* clear delta-transforms on all Objects which use the given IPO block */
1792 void clear_delta_obipo(Ipo *ipo)
1793 {
1794         Object *ob;
1795         
1796         /* only search if there's an IPO */
1797         if (ipo == NULL) 
1798                 return;
1799         
1800         /* search through all objects in database */
1801         for (ob= G.main->object.first; ob; ob= ob->id.next) {
1802                 /* can only update if not a library */
1803                 if (ob->id.lib == NULL) {
1804                         if (ob->ipo == ipo)  {
1805                                 memset(&ob->dloc, 0, 12);
1806                                 memset(&ob->drot, 0, 12);
1807                                 memset(&ob->dsize, 0, 12);
1808                         }
1809                 }
1810         }
1811 }
1812
1813 /* ***************************** IPO - DataAPI ********************************* */
1814
1815 // !!!!!!!!!!!!!!!!!!!!!!!!!!!! FIXME - BAD CRUFT WARNING !!!!!!!!!!!!!!!!!!!!!!!
1816
1817 /* These functions here should be replaced eventually by the Data API, as this is 
1818  * inflexible duplication...
1819  */
1820
1821 /* --------------------- Get Pointer API ----------------------------- */ 
1822
1823 /* get pointer to pose-channel's channel, but set appropriate flags first */
1824 // TODO: most channels (except euler rots, which are float-degr) are floats, so do we need type arg?
1825 void *get_pchan_ipo_poin (bPoseChannel *pchan, int adrcode)
1826 {
1827         void *poin= NULL;
1828         
1829         switch (adrcode) {
1830                 case AC_QUAT_W:
1831                         poin= &(pchan->quat[0]); 
1832                         pchan->flag |= POSE_ROT;
1833                         break;
1834                 case AC_QUAT_X:
1835                         poin= &(pchan->quat[1]); 
1836                         pchan->flag |= POSE_ROT;
1837                         break;
1838                 case AC_QUAT_Y:
1839                         poin= &(pchan->quat[2]); 
1840                         pchan->flag |= POSE_ROT;
1841                         break;
1842                 case AC_QUAT_Z:
1843                         poin= &(pchan->quat[3]); 
1844                         pchan->flag |= POSE_ROT;
1845                         break;
1846                         
1847                 case AC_EUL_X:
1848                         poin= &(pchan->eul[0]);
1849                         pchan->flag |= POSE_ROT;
1850                         //type= IPO_FLOAT_DEGR;
1851                         break;
1852                 case AC_EUL_Y:
1853                         poin= &(pchan->eul[1]);
1854                         pchan->flag |= POSE_ROT;
1855                         //type= IPO_FLOAT_DEGR;
1856                         break;
1857                 case AC_EUL_Z:
1858                         poin= &(pchan->eul[2]);
1859                         pchan->flag |= POSE_ROT;
1860                         //type= IPO_FLOAT_DEGR;
1861                         break;
1862                         
1863                 case AC_LOC_X:
1864                         poin= &(pchan->loc[0]); 
1865                         pchan->flag |= POSE_LOC;
1866                         break;
1867                 case AC_LOC_Y:
1868                         poin= &(pchan->loc[1]); 
1869                         pchan->flag |= POSE_LOC;
1870                         break;
1871                 case AC_LOC_Z:
1872                         poin= &(pchan->loc[2]); 
1873                         pchan->flag |= POSE_LOC;
1874                         break;
1875                 
1876                 case AC_SIZE_X:
1877                         poin= &(pchan->size[0]); 
1878                         pchan->flag |= POSE_SIZE;
1879                         break;
1880                 case AC_SIZE_Y:
1881                         poin= &(pchan->size[1]); 
1882                         pchan->flag |= POSE_SIZE;
1883                         break;
1884                 case AC_SIZE_Z:
1885                         poin= &(pchan->size[2]); 
1886                         pchan->flag |= POSE_SIZE;
1887                         break;
1888         }
1889         
1890         /* return pointer */
1891         return poin;
1892 }
1893
1894 /* get texture channel */
1895 static void *give_tex_poin (Tex *tex, int adrcode, int *type )
1896 {
1897         void *poin= NULL;
1898
1899         switch (adrcode) {
1900         case TE_NSIZE:
1901                 poin= &(tex->noisesize); break;
1902         case TE_TURB:
1903                 poin= &(tex->turbul); break;
1904         case TE_NDEPTH:
1905                 poin= &(tex->noisedepth); *type= IPO_SHORT; break;
1906         case TE_NTYPE:
1907                 poin= &(tex->noisetype); *type= IPO_SHORT; break;
1908         case TE_VNW1:
1909                 poin= &(tex->vn_w1); break;
1910         case TE_VNW2:
1911                 poin= &(tex->vn_w2); break;
1912         case TE_VNW3:
1913                 poin= &(tex->vn_w3); break;
1914         case TE_VNW4:
1915                 poin= &(tex->vn_w4); break;
1916         case TE_VNMEXP:
1917                 poin= &(tex->vn_mexp); break;
1918         case TE_ISCA:
1919                 poin= &(tex->ns_outscale); break;
1920         case TE_DISTA:
1921                 poin= &(tex->dist_amount); break;
1922         case TE_VN_COLT:
1923                 poin= &(tex->vn_coltype); *type= IPO_SHORT; break;
1924         case TE_VN_DISTM:
1925                 poin= &(tex->vn_distm); *type= IPO_SHORT; break;
1926         case TE_MG_TYP:
1927                 poin= &(tex->stype); *type= IPO_SHORT; break;
1928         case TE_MGH:
1929                 poin= &(tex->mg_H); break;
1930         case TE_MG_LAC:
1931                 poin= &(tex->mg_lacunarity); break;
1932         case TE_MG_OCT:
1933                 poin= &(tex->mg_octaves); break;
1934         case TE_MG_OFF:
1935                 poin= &(tex->mg_offset); break;
1936         case TE_MG_GAIN:
1937                 poin= &(tex->mg_gain); break;
1938         case TE_N_BAS1:
1939                 poin= &(tex->noisebasis); *type= IPO_SHORT; break;
1940         case TE_N_BAS2:
1941                 poin= &(tex->noisebasis2); *type= IPO_SHORT; break;
1942         case TE_COL_R:
1943                 poin= &(tex->rfac); break;
1944         case TE_COL_G:
1945                 poin= &(tex->gfac); break;
1946         case TE_COL_B:
1947                 poin= &(tex->bfac); break;
1948         case TE_BRIGHT:
1949                 poin= &(tex->bright); break;
1950         case TE_CONTRA:
1951                 poin= &(tex->contrast); break;
1952         }
1953         
1954         /* return pointer */
1955         return poin;
1956 }
1957
1958 /* get texture-slot/mapping channel */
1959 void *give_mtex_poin (MTex *mtex, int adrcode)
1960 {
1961         void *poin= NULL;
1962         
1963         switch (adrcode) {
1964         case MAP_OFS_X:
1965                 poin= &(mtex->ofs[0]); break;
1966         case MAP_OFS_Y:
1967                 poin= &(mtex->ofs[1]); break;
1968         case MAP_OFS_Z:
1969                 poin= &(mtex->ofs[2]); break;
1970         case MAP_SIZE_X:
1971                 poin= &(mtex->size[0]); break;
1972         case MAP_SIZE_Y:
1973                 poin= &(mtex->size[1]); break;
1974         case MAP_SIZE_Z:
1975                 poin= &(mtex->size[2]); break;
1976         case MAP_R:
1977                 poin= &(mtex->r); break;
1978         case MAP_G:
1979                 poin= &(mtex->g); break;
1980         case MAP_B:
1981                 poin= &(mtex->b); break;
1982         case MAP_DVAR:
1983                 poin= &(mtex->def_var); break;
1984         case MAP_COLF:
1985                 poin= &(mtex->colfac); break;
1986         case MAP_NORF:
1987                 poin= &(mtex->norfac); break;
1988         case MAP_VARF:
1989                 poin= &(mtex->varfac); break;
1990         case MAP_DISP:
1991                 poin= &(mtex->dispfac); break;
1992         }
1993         
1994         /* return pointer */
1995         return poin;
1996 }
1997
1998 /* GS reads the memory pointed at in a specific ordering. There are,
1999  * however two definitions for it. I have jotted them down here, both,
2000  * but I think the first one is actually used. The thing is that
2001  * big-endian systems might read this the wrong way round. OTOH, we
2002  * constructed the IDs that are read out with this macro explicitly as
2003  * well. I expect we'll sort it out soon... */
2004
2005 /* from blendef: */
2006 #define GS(a)   (*((short *)(a)))
2007
2008 /* from misc_util: flip the bytes from x  */
2009 /*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
2010
2011
2012 /* general function to get pointer to source/destination data  */
2013 void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
2014 {
2015         void *poin= NULL;
2016         MTex *mtex= NULL;
2017
2018         /* most channels will have float data, but those with other types will override this */
2019         *type= IPO_FLOAT;
2020
2021         /* data is divided into 'blocktypes' based on ID-codes */
2022         switch (GS(id->name)) {
2023                 case ID_OB: /* object channels -----------------------------  */
2024                 {
2025                         Object *ob= (Object *)id;
2026                         
2027                         switch (icu->adrcode) {
2028                         case OB_LOC_X:
2029                                 poin= &(ob->loc[0]); break;
2030                         case OB_LOC_Y:
2031                                 poin= &(ob->loc[1]); break;
2032                         case OB_LOC_Z:
2033                                 poin= &(ob->loc[2]); break;
2034                         case OB_DLOC_X:
2035                                 poin= &(ob->dloc[0]); break;
2036                         case OB_DLOC_Y:
2037                                 poin= &(ob->dloc[1]); break;
2038                         case OB_DLOC_Z:
2039                                 poin= &(ob->dloc[2]); break;
2040                         
2041                         case OB_ROT_X:
2042                                 poin= &(ob->rot[0]); *type= IPO_FLOAT_DEGR; break;
2043                         case OB_ROT_Y:
2044                                 poin= &(ob->rot[1]); *type= IPO_FLOAT_DEGR; break;
2045                         case OB_ROT_Z:
2046                                 poin= &(ob->rot[2]); *type= IPO_FLOAT_DEGR; break;
2047                         case OB_DROT_X:
2048                                 poin= &(ob->drot[0]); *type= IPO_FLOAT_DEGR; break;
2049                         case OB_DROT_Y:
2050                                 poin= &(ob->drot[1]); *type= IPO_FLOAT_DEGR; break;
2051                         case OB_DROT_Z:
2052                                 poin= &(ob->drot[2]); *type= IPO_FLOAT_DEGR; break;
2053                                 
2054                         case OB_SIZE_X:
2055                                 poin= &(ob->size[0]); break;
2056                         case OB_SIZE_Y:
2057                                 poin= &(ob->size[1]); break;
2058                         case OB_SIZE_Z:
2059                                 poin= &(ob->size[2]); break;
2060                         case OB_DSIZE_X:
2061                                 poin= &(ob->dsize[0]); break;
2062                         case OB_DSIZE_Y:
2063                                 poin= &(ob->dsize[1]); break;
2064                         case OB_DSIZE_Z:
2065                                 poin= &(ob->dsize[2]); break;
2066                         
2067                         case OB_LAY:
2068                                 poin= &(ob->lay); *type= IPO_INT_BIT; break;
2069                                 
2070                         case OB_COL_R:  
2071                                 poin= &(ob->col[0]); break;
2072                         case OB_COL_G:
2073                                 poin= &(ob->col[1]); break;
2074                         case OB_COL_B:
2075                                 poin= &(ob->col[2]); break;
2076                         case OB_COL_A:
2077                                 poin= &(ob->col[3]); break;
2078                                 
2079                         case OB_PD_FSTR:
2080                                 if (ob->pd) poin= &(ob->pd->f_strength);
2081                                 break;
2082                         case OB_PD_FFALL:
2083                                 if (ob->pd) poin= &(ob->pd->f_power);
2084                                 break;
2085                         case OB_PD_SDAMP:
2086                                 if (ob->pd) poin= &(ob->pd->pdef_damp);
2087                                 break;
2088                         case OB_PD_RDAMP:
2089                                 if (ob->pd) poin= &(ob->pd->pdef_rdamp);
2090                                 break;
2091                         case OB_PD_PERM:
2092                                 if (ob->pd) poin= &(ob->pd->pdef_perm);
2093                                 break;
2094                         case OB_PD_FMAXD:
2095                                 if (ob->pd) poin= &(ob->pd->maxdist);
2096                                 break;
2097                         }
2098                 }
2099                         break;
2100                 case ID_MA: /* material channels -----------------------------  */
2101                 {
2102                         Material *ma= (Material *)id;
2103                         
2104                         switch (icu->adrcode) {
2105                         case MA_COL_R:
2106                                 poin= &(ma->r); break;
2107                         case MA_COL_G:
2108                                 poin= &(ma->g); break;
2109                         case MA_COL_B:
2110                                 poin= &(ma->b); break;
2111                         case MA_SPEC_R:
2112                                 poin= &(ma->specr); break;
2113                         case MA_SPEC_G:
2114                                 poin= &(ma->specg); break;
2115                         case MA_SPEC_B:
2116                                 poin= &(ma->specb); break;
2117                         case MA_MIR_R:
2118                                 poin= &(ma->mirr); break;
2119                         case MA_MIR_G:
2120                                 poin= &(ma->mirg); break;
2121                         case MA_MIR_B:
2122                                 poin= &(ma->mirb); break;
2123                         case MA_REF:
2124                                 poin= &(ma->ref); break;
2125                         case MA_ALPHA:
2126                                 poin= &(ma->alpha); break;
2127                         case MA_EMIT:
2128                                 poin= &(ma->emit); break;
2129                         case MA_AMB:
2130                                 poin= &(ma->amb); break;
2131                         case MA_SPEC:
2132                                 poin= &(ma->spec); break;
2133                         case MA_HARD:
2134                                 poin= &(ma->har); *type= IPO_SHORT; break;
2135                         case MA_SPTR:
2136                                 poin= &(ma->spectra); break;
2137                         case MA_IOR:
2138                                 poin= &(ma->ang); break;
2139                         case MA_MODE:
2140                                 poin= &(ma->mode); *type= IPO_INT_BIT; break; // evil... dumping bitflags directly to user!
2141                         case MA_HASIZE:
2142                                 poin= &(ma->hasize); break;
2143                         case MA_TRANSLU:
2144                                 poin= &(ma->translucency); break;
2145                         case MA_RAYM:
2146                                 poin= &(ma->ray_mirror); break;
2147                         case MA_FRESMIR:
2148                                 poin= &(ma->fresnel_mir); break;
2149                         case MA_FRESMIRI:
2150                                 poin= &(ma->fresnel_mir_i); break;
2151                         case MA_FRESTRA:
2152                                 poin= &(ma->fresnel_tra); break;
2153                         case MA_FRESTRAI:
2154                                 poin= &(ma->fresnel_tra_i); break;
2155                         case MA_ADD:
2156                                 poin= &(ma->add); break;
2157                         }
2158                         
2159                         if (poin == NULL) {
2160                                 if (icu->adrcode & MA_MAP1) mtex= ma->mtex[0];
2161                                 else if (icu->adrcode & MA_MAP2) mtex= ma->mtex[1];
2162                                 else if (icu->adrcode & MA_MAP3) mtex= ma->mtex[2];
2163                                 else if (icu->adrcode & MA_MAP4) mtex= ma->mtex[3];
2164                                 else if (icu->adrcode & MA_MAP5) mtex= ma->mtex[4];
2165                                 else if (icu->adrcode & MA_MAP6) mtex= ma->mtex[5];
2166                                 else if (icu->adrcode & MA_MAP7) mtex= ma->mtex[6];
2167                                 else if (icu->adrcode & MA_MAP8) mtex= ma->mtex[7];
2168                                 else if (icu->adrcode & MA_MAP9) mtex= ma->mtex[8];
2169                                 else if (icu->adrcode & MA_MAP10) mtex= ma->mtex[9];
2170                                 else if (icu->adrcode & MA_MAP12) mtex= ma->mtex[11];
2171                                 else if (icu->adrcode & MA_MAP11) mtex= ma->mtex[10];
2172                                 else if (icu->adrcode & MA_MAP13) mtex= ma->mtex[12];
2173                                 else if (icu->adrcode & MA_MAP14) mtex= ma->mtex[13];
2174                                 else if (icu->adrcode & MA_MAP15) mtex= ma->mtex[14];
2175                                 else if (icu->adrcode & MA_MAP16) mtex= ma->mtex[15];
2176                                 else if (icu->adrcode & MA_MAP17) mtex= ma->mtex[16];
2177                                 else if (icu->adrcode & MA_MAP18) mtex= ma->mtex[17];
2178                                 
2179                                 if (mtex)
2180                                         poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
2181                         }
2182                 }
2183                         break;
2184                 case ID_TE: /* texture channels -----------------------------  */
2185                 {
2186                         Tex *tex= (Tex *)id;
2187                         
2188                         if (tex) 
2189                                 poin= give_tex_poin(tex, icu->adrcode, type);
2190                 }
2191                         break;
2192                 case ID_SEQ: /* sequence channels -----------------------------  */
2193                 {
2194                         Sequence *seq= (Sequence *)id;
2195                         
2196                         switch (icu->adrcode) {
2197                         case SEQ_FAC1:
2198                                 poin= &(seq->facf0); break;
2199                         }
2200                 }
2201                         break;
2202                 case ID_CU: /* curve channels -----------------------------  */
2203                 {
2204                         poin= &(icu->curval);
2205                 }
2206                         break;
2207                 case ID_KE: /* shapekey channels -----------------------------  */
2208                 {
2209                         Key *key= (Key *)id;
2210                         KeyBlock *kb;
2211                         
2212                         for(kb= key->block.first; kb; kb= kb->next) {
2213                                 if (kb->adrcode == icu->adrcode)
2214                                         break;
2215                         }
2216                         
2217                         if (kb)
2218                                 poin= &(kb->curval);
2219                 }
2220                         break;
2221                 case ID_WO: /* world channels -----------------------------  */
2222                 {
2223                         World *wo= (World *)id;
2224                         
2225                         switch (icu->adrcode) {
2226                         case WO_HOR_R:
2227                                 poin= &(wo->horr); break;
2228                         case WO_HOR_G:
2229                                 poin= &(wo->horg); break;
2230                         case WO_HOR_B:
2231                                 poin= &(wo->horb); break;
2232                         case WO_ZEN_R:
2233                                 poin= &(wo->zenr); break;
2234                         case WO_ZEN_G:
2235                                 poin= &(wo->zeng); break;
2236                         case WO_ZEN_B:
2237                                 poin= &(wo->zenb); break;
2238                         
2239                         case WO_EXPOS:
2240                                 poin= &(wo->exposure); break;
2241                         
2242                         case WO_MISI:
2243                                 poin= &(wo->misi); break;
2244                         case WO_MISTDI:
2245                                 poin= &(wo->mistdist); break;
2246                         case WO_MISTSTA:
2247                                 poin= &(wo->miststa); break;
2248                         case WO_MISTHI:
2249                                 poin= &(wo->misthi); break;
2250                         
2251                         case WO_STAR_R:
2252                                 poin= &(wo->starr); break;
2253                         case WO_STAR_G:
2254                                 poin= &(wo->starg); break;
2255                         case WO_STAR_B:
2256                                 poin= &(wo->starb); break;
2257                         
2258                         case WO_STARDIST:
2259                                 poin= &(wo->stardist); break;
2260                         case WO_STARSIZE:
2261                                 poin= &(wo->starsize); break;
2262                         }
2263                         
2264                         if (poin == NULL) {
2265                                 if (icu->adrcode & MA_MAP1) mtex= wo->mtex[0];
2266                                 else if (icu->adrcode & MA_MAP2) mtex= wo->mtex[1];
2267                                 else if (icu->adrcode & MA_MAP3) mtex= wo->mtex[2];
2268                                 else if (icu->adrcode & MA_MAP4) mtex= wo->mtex[3];
2269                                 else if (icu->adrcode & MA_MAP5) mtex= wo->mtex[4];
2270                                 else if (icu->adrcode & MA_MAP6) mtex= wo->mtex[5];
2271                                 else if (icu->adrcode & MA_MAP7) mtex= wo->mtex[6];
2272                                 else if (icu->adrcode & MA_MAP8) mtex= wo->mtex[7];
2273                                 else if (icu->adrcode & MA_MAP9) mtex= wo->mtex[8];
2274                                 else if (icu->adrcode & MA_MAP10) mtex= wo->mtex[9];
2275                                 else if (icu->adrcode & MA_MAP11) mtex= wo->mtex[10];
2276                                 else if (icu->adrcode & MA_MAP12) mtex= wo->mtex[11];
2277                                 else if (icu->adrcode & MA_MAP13) mtex= wo->mtex[12];
2278                                 else if (icu->adrcode & MA_MAP14) mtex= wo->mtex[13];
2279                                 else if (icu->adrcode & MA_MAP15) mtex= wo->mtex[14];
2280                                 else if (icu->adrcode & MA_MAP16) mtex= wo->mtex[15];
2281                                 else if (icu->adrcode & MA_MAP17) mtex= wo->mtex[16];
2282                                 else if (icu->adrcode & MA_MAP18) mtex= wo->mtex[17];
2283                                 
2284                                 if (mtex)
2285                                         poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
2286                         }
2287                 }
2288                         break;
2289                 case ID_LA: /* lamp channels -----------------------------  */
2290                 {
2291                         Lamp *la= (Lamp *)id;
2292                         
2293                         switch (icu->adrcode) {
2294                         case LA_ENERGY:
2295                                 poin= &(la->energy); break;             
2296                         case LA_COL_R:
2297                                 poin= &(la->r); break;
2298                         case LA_COL_G:
2299                                 poin= &(la->g); break;
2300                         case LA_COL_B:
2301                                 poin= &(la->b); break;
2302                         case LA_DIST:
2303                                 poin= &(la->dist); break;               
2304                         case LA_SPOTSI:
2305                                 poin= &(la->spotsize); break;
2306                         case LA_SPOTBL:
2307                                 poin= &(la->spotblend); break;
2308                         case LA_QUAD1:
2309                                 poin= &(la->att1); break;
2310                         case LA_QUAD2:
2311                                 poin= &(la->att2); break;
2312                         case LA_HALOINT:
2313                                 poin= &(la->haint); break;
2314                         }
2315                         
2316                         if (poin == NULL) {
2317                                 if (icu->adrcode & MA_MAP1) mtex= la->mtex[0];
2318                                 else if (icu->adrcode & MA_MAP2) mtex= la->mtex[1];
2319                                 else if (icu->adrcode & MA_MAP3) mtex= la->mtex[2];
2320                                 else if (icu->adrcode & MA_MAP4) mtex= la->mtex[3];
2321                                 else if (icu->adrcode & MA_MAP5) mtex= la->mtex[4];
2322                                 else if (icu->adrcode & MA_MAP6) mtex= la->mtex[5];
2323                                 else if (icu->adrcode & MA_MAP7) mtex= la->mtex[6];
2324                                 else if (icu->adrcode & MA_MAP8) mtex= la->mtex[7];
2325                                 else if (icu->adrcode & MA_MAP9) mtex= la->mtex[8];
2326                                 else if (icu->adrcode & MA_MAP10) mtex= la->mtex[9];
2327                                 else if (icu->adrcode & MA_MAP11) mtex= la->mtex[10];
2328                                 else if (icu->adrcode & MA_MAP12) mtex= la->mtex[11];
2329                                 else if (icu->adrcode & MA_MAP13) mtex= la->mtex[12];
2330                                 else if (icu->adrcode & MA_MAP14) mtex= la->mtex[13];
2331                                 else if (icu->adrcode & MA_MAP15) mtex= la->mtex[14];
2332                                 else if (icu->adrcode & MA_MAP16) mtex= la->mtex[15];
2333                                 else if (icu->adrcode & MA_MAP17) mtex= la->mtex[16];
2334                                 else if (icu->adrcode & MA_MAP18) mtex= la->mtex[17];
2335                                 
2336                                 if (mtex)
2337                                         poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
2338                         }
2339                 }
2340                         break;
2341                 case ID_CA: /* camera channels -----------------------------  */
2342                 {
2343                         Camera *ca= (Camera *)id;
2344                         
2345                         switch (icu->adrcode) {
2346                         case CAM_LENS:
2347                                 if (ca->type == CAM_ORTHO)
2348                                         poin= &(ca->ortho_scale);
2349                                 else
2350                                         poin= &(ca->lens); 
2351                                 break;
2352                         case CAM_STA:
2353                                 poin= &(ca->clipsta); break;
2354                         case CAM_END:
2355                                 poin= &(ca->clipend); break;
2356                                 
2357                         case CAM_YF_APERT:
2358                                 poin= &(ca->YF_aperture); break;
2359                         case CAM_YF_FDIST:
2360                                 poin= &(ca->YF_dofdist); break;
2361                                 
2362                         case CAM_SHIFT_X:
2363                                 poin= &(ca->shiftx); break;
2364                         case CAM_SHIFT_Y:
2365                                 poin= &(ca->shifty); break;
2366                         }
2367                 }
2368                         break;
2369                 case ID_SO: /* sound channels -----------------------------  */
2370                 {
2371                         bSound *snd= (bSound *)id;
2372                         
2373                         switch (icu->adrcode) {
2374                         case SND_VOLUME:
2375                                 poin= &(snd->volume); break;
2376                         case SND_PITCH:
2377                                 poin= &(snd->pitch); break;
2378                         case SND_PANNING:
2379                                 poin= &(snd->panning); break;
2380                         case SND_ATTEN:
2381                                 poin= &(snd->attenuation); break;
2382                         }
2383                 }
2384                         break;
2385                 case ID_PA: /* particle channels -----------------------------  */
2386                 {
2387                         ParticleSettings *part= (ParticleSettings *)id;
2388                         
2389                         switch (icu->adrcode) {
2390                         case PART_EMIT_FREQ:
2391                         case PART_EMIT_LIFE:
2392                         case PART_EMIT_VEL:
2393                         case PART_EMIT_AVE:
2394                         case PART_EMIT_SIZE:
2395                                 poin= NULL; 
2396                                 break;
2397                         
2398                         case PART_CLUMP:
2399                                 poin= &(part->clumpfac); break;
2400                         case PART_AVE:
2401                                 poin= &(part->avefac); break;
2402                         case PART_SIZE:
2403                                 poin= &(part->size); break;
2404                         case PART_DRAG:
2405                                 poin= &(part->dragfac); break;
2406                         case PART_BROWN:
2407                                 poin= &(part->brownfac); break;
2408                         case PART_DAMP:
2409                                 poin= &(part->dampfac); break;
2410                         case PART_LENGTH:
2411                                 poin= &(part->length); break;
2412                         case PART_GRAV_X:
2413                                 poin= &(part->acc[0]); break;
2414                         case PART_GRAV_Y:
2415                                 poin= &(part->acc[1]); break;
2416                         case PART_GRAV_Z:
2417                                 poin= &(part->acc[2]); break;
2418                         case PART_KINK_AMP:
2419                                 poin= &(part->kink_amp); break;
2420                         case PART_KINK_FREQ:
2421                                 poin= &(part->kink_freq); break;
2422                         case PART_KINK_SHAPE:
2423                                 poin= &(part->kink_shape); break;
2424                         case PART_BB_TILT:
2425                                 poin= &(part->bb_tilt); break;
2426                                 
2427                         case PART_PD_FSTR:
2428                                 if (part->pd) poin= &(part->pd->f_strength);
2429                                 break;
2430                         case PART_PD_FFALL:
2431                                 if (part->pd) poin= &(part->pd->f_power);
2432                                 break;
2433                         case PART_PD_FMAXD:
2434                                 if (part->pd) poin= &(part->pd->maxdist);
2435                                 break;
2436                         case PART_PD2_FSTR:
2437                                 if (part->pd2) poin= &(part->pd2->f_strength);
2438                                 break;
2439                         case PART_PD2_FFALL:
2440                                 if (part->pd2) poin= &(part->pd2->f_power);
2441                                 break;
2442                         case PART_PD2_FMAXD:
2443                                 if (part->pd2) poin= &(part->pd2->maxdist);
2444                                 break;
2445                         }
2446                 }
2447                         break;
2448         }
2449
2450         /* return pointer */
2451         return poin;
2452 }
2453
2454 /* --------------------- IPO-Curve Limits ----------------------------- */
2455
2456 /* set limits for IPO-curve 
2457  * Note: must be synced with UI and PyAPI
2458  */
2459 void set_icu_vars (IpoCurve *icu)
2460 {
2461         /* defaults. 0.0 for y-extents makes these ignored */
2462         icu->ymin= icu->ymax= 0.0;
2463         icu->ipo= IPO_BEZ;
2464         
2465         switch (icu->blocktype) {
2466                 case ID_OB: /* object channels -----------------------------  */
2467                 {
2468                         if (icu->adrcode == OB_LAY) {
2469                                 icu->ipo= IPO_CONST;
2470                                 icu->vartype= IPO_BITS;
2471                         }
2472                 }
2473                         break;
2474                 case ID_MA: /* material channels -----------------------------  */
2475                 {
2476                         if (icu->adrcode < MA_MAP1) {
2477                                 switch (icu->adrcode) {
2478                                 case MA_HASIZE:
2479                                         icu->ymax= 10000.0; break;
2480                                 case MA_HARD:
2481                                         icu->ymax= 511.0; break;
2482                                 case MA_SPEC:
2483                                         icu->ymax= 2.0; break;
2484                                 case MA_MODE:
2485                                         icu->ipo= IPO_CONST;
2486                                         icu->vartype= IPO_BITS; break;
2487                                 case MA_RAYM:
2488                                         icu->ymax= 1.0; break;
2489                                 case MA_TRANSLU:
2490                                         icu->ymax= 1.0; break;
2491                                 case MA_IOR:
2492                                         icu->ymin= 1.0;
2493                                         icu->ymax= 3.0; break;
2494                                 case MA_FRESMIR:
2495                                         icu->ymax= 5.0; break;
2496                                 case MA_FRESMIRI:
2497                                         icu->ymin= 1.0;
2498                                         icu->ymax= 5.0; break;
2499                                 case MA_FRESTRA:
2500                                         icu->ymax= 5.0; break;
2501                                 case MA_FRESTRAI:
2502                                         icu->ymin= 1.0;
2503                                         icu->ymax= 5.0; break;
2504                                 case MA_ADD:
2505                                         icu->ymax= 1.0; break;
2506                                 case MA_EMIT:
2507                                         icu->ymax= 2.0; break;
2508                                 default:
2509                                         icu->ymax= 1.0; break;
2510                                 }
2511                         }
2512                         else {
2513                                 switch (icu->adrcode & (MA_MAP1-1)) {
2514                                 case MAP_OFS_X:
2515                                 case MAP_OFS_Y:
2516                                 case MAP_OFS_Z:
2517                                 case MAP_SIZE_X:
2518                                 case MAP_SIZE_Y:
2519                                 case MAP_SIZE_Z:
2520                                         icu->ymax= 1000.0;
2521                                         icu->ymin= -1000.0;
2522                                         break;
2523                                 case MAP_R:
2524                                 case MAP_G:
2525                                 case MAP_B:
2526                                 case MAP_DVAR:
2527                                 case MAP_COLF:
2528                                 case MAP_VARF:
2529                                 case MAP_DISP:
2530                                         icu->ymax= 1.0;
2531                                         break;
2532                                 case MAP_NORF:
2533                                         icu->ymax= 25.0;
2534                                         break;
2535                                 }
2536                         }
2537                 }
2538                         break;
2539                 case ID_TE: /* texture channels -----------------------------  */
2540                 {
2541                         switch (icu->adrcode & (MA_MAP1-1)) {
2542                                 case TE_NSIZE:
2543                                         icu->ymin= 0.0001f;
2544                                         icu->ymax= 2.0f; 
2545                                         break;
2546                                 case TE_NDEPTH:
2547                                         icu->vartype= IPO_SHORT;
2548                                         icu->ipo= IPO_CONST;
2549                                         icu->ymax= 6.0f; 
2550                                         break;
2551                                 case TE_NTYPE:
2552                                         icu->vartype= IPO_SHORT;
2553                                         icu->ipo= IPO_CONST;
2554                                         icu->ymax= 1.0f; 
2555                                         break;
2556                                 case TE_TURB:
2557                                         icu->ymax= 200.0f; 
2558                                         break;
2559                                 case TE_VNW1:
2560                                 case TE_VNW2:
2561                                 case TE_VNW3:
2562                                 case TE_VNW4:
2563                                         icu->ymax= 2.0f;
2564                                         icu->ymin= -2.0f; 
2565                                         break;
2566                                 case TE_VNMEXP:
2567                                         icu->ymax= 10.0f;
2568                                         icu->ymin= 0.01f; 
2569                                         break;
2570                                 case TE_VN_DISTM:
2571                                         icu->vartype= IPO_SHORT;
2572                                         icu->ipo= IPO_CONST;
2573                                         icu->ymax= 6.0f; 
2574                                         break;
2575                                 case TE_VN_COLT:
2576                                         icu->vartype= IPO_SHORT;
2577                                         icu->ipo= IPO_CONST;
2578                                         icu->ymax= 3.0f; 
2579                                         break;
2580                                 case TE_ISCA:
2581                                         icu->ymax= 10.0f;
2582                                         icu->ymin= 0.01f; 
2583                                         break;
2584                                 case TE_DISTA:
2585                                         icu->ymax= 10.0f; 
2586                                         break;
2587                                 case TE_MG_TYP:
2588                                         icu->vartype= IPO_SHORT;
2589                                         icu->ipo= IPO_CONST;
2590                                         icu->ymax= 6.0f; 
2591                                         break;
2592                                 case TE_MGH:
2593                                         icu->ymin= 0.0001f;
2594                                         icu->ymax= 2.0f; 
2595                                         break;
2596                                 case TE_MG_LAC:
2597                                 case TE_MG_OFF:
2598                                 case TE_MG_GAIN:
2599                                         icu->ymax= 6.0f; break;
2600                                 case TE_MG_OCT:
2601                                         icu->ymax= 8.0f; break;
2602                                 case TE_N_BAS1:
2603                                 case TE_N_BAS2:
2604                                         icu->vartype= IPO_SHORT;
2605                                         icu->ipo= IPO_CONST;
2606                                         icu->ymax= 8.0f; 
2607                                         break;
2608                                 case TE_COL_R:
2609                                         icu->ymax= 0.0f; break;
2610                                 case TE_COL_G:
2611                                         icu->ymax= 2.0f; break;
2612                                 case TE_COL_B:
2613                                         icu->ymax= 2.0f; break;
2614                                 case TE_BRIGHT:
2615                                         icu->ymax= 2.0f; break;
2616                                 case TE_CONTRA:
2617                                         icu->ymax= 5.0f; break; 
2618                         }
2619                 }
2620                         break;
2621                 case ID_SEQ: /* sequence channels -----------------------------  */
2622                 {
2623                         icu->ymax= 1.0f;
2624                 }
2625                         break;
2626                 case ID_CU: /* curve channels -----------------------------  */
2627                 {
2628                         icu->ymax= 1.0f;
2629                 }
2630                         break;
2631                 case ID_WO: /* world channels -----------------------------  */
2632                 {
2633                         if (icu->adrcode < MA_MAP1) {
2634                                 switch (icu->adrcode) {
2635                                 case WO_EXPOS:
2636                                         icu->ymax= 5.0f; break;
2637                                 
2638                                 case WO_MISTDI:
2639                                 case WO_MISTSTA:
2640                                 case WO_MISTHI:
2641                                 case WO_STARDIST:
2642                                 case WO_STARSIZE:
2643                                         break;
2644                                         
2645                                 default:
2646                                         icu->ymax= 1.0f;
2647                                         break;
2648                                 }
2649                         }
2650                         else {
2651                                 switch (icu->adrcode & (MA_MAP1-1)) {
2652                                 case MAP_OFS_X:
2653                                 case MAP_OFS_Y:
2654                                 case MAP_OFS_Z:
2655                                 case MAP_SIZE_X:
2656                                 case MAP_SIZE_Y:
2657                                 case MAP_SIZE_Z:
2658                                         icu->ymax= 100.0f;
2659                                         icu->ymin= -100.0f;
2660                                         break;
2661                                 case MAP_R:
2662                                 case MAP_G:
2663                                 case MAP_B:
2664                                 case MAP_DVAR:
2665                                 case MAP_COLF:
2666                                 case MAP_NORF:
2667                                 case MAP_VARF:
2668                                 case MAP_DISP:
2669                                         icu->ymax= 1.0f;
2670                                 }
2671                         }
2672                 }
2673                         break;
2674                 case ID_LA: /* lamp channels -----------------------------  */
2675                 {
2676                         if (icu->adrcode < MA_MAP1) {
2677                                 switch (icu->adrcode) {
2678                                 case LA_ENERGY:
2679                                 case LA_DIST:
2680                                         break;          
2681                                 
2682                                 case LA_COL_R:
2683                                 case LA_COL_G:
2684                                 case LA_COL_B:
2685                                 case LA_SPOTBL:
2686                                 case LA_QUAD1:
2687                                 case LA_QUAD2:
2688                                         icu->ymax= 1.0f; break;
2689                                         
2690                                 case LA_SPOTSI:
2691                                         icu->ymax= 180.0f; break;
2692                                 
2693                                 case LA_HALOINT:
2694                                         icu->ymax= 5.0f; break;
2695                                 }
2696                         }
2697                         else {
2698                                 switch (icu->adrcode & (MA_MAP1-1)) {
2699                                 case MAP_OFS_X:
2700                                 case MAP_OFS_Y:
2701                                 case MAP_OFS_Z:
2702                                 case MAP_SIZE_X:
2703                                 case MAP_SIZE_Y:
2704                                 case MAP_SIZE_Z:
2705                                         icu->ymax= 100.0f;
2706                                         icu->ymin= -100.0f;
2707                                         break;
2708                                 case MAP_R:
2709                                 case MAP_G:
2710                                 case MAP_B:
2711                                 case MAP_DVAR:
2712                                 case MAP_COLF:
2713                                 case MAP_NORF:
2714                                 case MAP_VARF:
2715                                 case MAP_DISP:
2716                                         icu->ymax= 1.0f;
2717                                 }
2718                         }
2719                 }       
2720                         break;
2721                 case ID_CA: /* camera channels -----------------------------  */
2722                 {
2723                         switch (icu->adrcode) {
2724                         case CAM_LENS:
2725                                 icu->ymin= 1.0f;
2726                                 icu->ymax= 1000.0f;
2727                                 break;
2728                         case CAM_STA:
2729                                 icu->ymin= 0.001f;
2730                                 break;
2731                         case CAM_END:
2732                                 icu->ymin= 0.1f;
2733                                 break;
2734                                 
2735                         case CAM_YF_APERT:
2736                                 icu->ymin = 0.0f;
2737                                 icu->ymax = 2.0f;
2738                                 break;
2739                         case CAM_YF_FDIST:
2740                                 icu->ymin = 0.0f;
2741                                 icu->ymax = 5000.0f;
2742                                 break;
2743                                 
2744                         case CAM_SHIFT_X:
2745                         case CAM_SHIFT_Y:
2746                                 icu->ymin= -2.0f;
2747                                 icu->ymax= 2.0f;
2748                                 break;
2749                         }
2750                 }
2751                         break;
2752                 case ID_SO: /* sound channels -----------------------------  */
2753                 {
2754                         switch (icu->adrcode) {
2755                         case SND_VOLUME:
2756                                 icu->ymin= 0.0f;
2757                                 icu->ymax= 1.0f;
2758                                 break;
2759                         case SND_PITCH:
2760                                 icu->ymin= -12.0f;
2761                                 icu->ymin= 12.0f;
2762                                 break;
2763                         case SND_PANNING:
2764                                 icu->ymin= 0.0f;
2765                                 icu->ymax= 1.0f;
2766                                 break;
2767                         case SND_ATTEN:
2768                                 icu->ymin= 0.0f;
2769                                 icu->ymin= 1.0f;
2770                                 break;
2771                         }
2772                 }
2773                         break;
2774                 case ID_PA: /* particle channels -----------------------------  */
2775                 {
2776                         switch (icu->adrcode) {
2777                         case PART_EMIT_LIFE:
2778                         case PART_SIZE:
2779                         case PART_KINK_FREQ:
2780                         case PART_EMIT_VEL:
2781                         case PART_EMIT_AVE:
2782                         case PART_EMIT_SIZE:
2783                                 icu->ymin= 0.0f;
2784                                 break;
2785                         case PART_CLUMP:
2786                                 icu->ymin= -1.0f;
2787                                 icu->ymax= 1.0f;
2788                                 break;
2789                         case PART_DRAG:
2790                         case PART_DAMP:
2791                         case PART_LENGTH:
2792                                 icu->ymin= 0.0f;
2793                                 icu->ymax= 1.0f;
2794                                 break;
2795                         case PART_KINK_SHAPE:
2796                                 icu->ymin= -0.999f;
2797                                 icu->ymax= 0.999f;
2798                                 break;
2799                         }
2800                 }
2801                         break;
2802                 case ID_CO: /* constraint channels -----------------------------  */
2803                 {
2804                         icu->ymin= 0.0f;
2805                         icu->ymax= 1.0f;
2806                 }
2807                         break;
2808         }
2809         
2810         /* by default, slider limits will be icu->ymin and icu->ymax */
2811         icu->slide_min= icu->ymin;
2812         icu->slide_max= icu->ymax;
2813 }
2814
2815 /* --------------------- Pointer I/O API ----------------------------- */
2816  
2817 /* write the given value directly into the given pointer */
2818 void write_ipo_poin (void *poin, int type, float val)
2819 {
2820         /* Note: we only support a limited number of types, with the value
2821          * to set needing to be cast to the appropriate type first
2822          *      -> (float to integer conversions could be slow)
2823          */
2824         switch(type) {
2825         case IPO_FLOAT:
2826                 *((float *)poin)= val;
2827                 break;
2828                 
2829         case IPO_FLOAT_DEGR: /* special hack for rotation so that it fits on same axis as other transforms */
2830                 *((float *)poin)= (float)(val * M_PI_2 / 9.0);
2831                 break;
2832                 
2833         case IPO_INT:
2834         case IPO_INT_BIT: // fixme... directly revealing bitflag combinations is evil!
2835         case IPO_LONG:
2836                 *((int *)poin)= (int)val;
2837                 break;
2838                 
2839         case IPO_SHORT:
2840         case IPO_SHORT_BIT: // fixme... directly revealing bitflag combinations is evil!
2841                 *((short *)poin)= (short)val;
2842                 break;
2843                 
2844         case IPO_CHAR:
2845         case IPO_CHAR_BIT: // fixme... directly revealing bitflag combinations is evil!
2846                 *((char *)poin)= (char)val;
2847                 break;
2848         }
2849 }
2850
2851 /* read the value from the pointer that was obtained */
2852 float read_ipo_poin (void *poin, int type)
2853 {
2854         float val = 0.0;
2855         
2856         /* Note: we only support a limited number of types, with the value
2857          * to set needing to be cast to the appropriate type first
2858          *      -> (int to float conversions may loose accuracy in rare cases)
2859          */
2860         switch (type) {
2861         case IPO_FLOAT:
2862                 val= *((float *)poin);
2863                 break;
2864                 
2865         case IPO_FLOAT_DEGR: /* special hack for rotation so that it fits on same axis as other transforms */
2866                 val= *( (float *)poin);
2867                 val = (float)(val / (M_PI_2/9.0));
2868                 break;
2869         
2870         case IPO_INT:
2871         case IPO_INT_BIT: // fixme... directly revealing bitflag combinations is evil!
2872         case IPO_LONG:
2873                 val= (float)( *((int *)poin) );
2874                 break;
2875                 
2876         case IPO_SHORT:
2877         case IPO_SHORT_BIT: // fixme... directly revealing bitflag combinations is evil!
2878                 val= *((short *)poin);
2879                 break;
2880         
2881         case IPO_CHAR:
2882         case IPO_CHAR_BIT: // fixme... directly revealing bitflag combinations is evil
2883                 val= *((char *)poin);
2884                 break;
2885         }
2886         
2887         /* return value */
2888         return val;
2889 }
2890
2891 // !!!!!!!!!!!!!!!!!!!!!!!!!!!! FIXME - BAD CRUFT WARNING !!!!!!!!!!!!!!!!!!!!!!!
2892
2893
2894 /* ***************************** IPO <--> GameEngine Interface ********************************* */
2895
2896 /* channels is max 32 items, allocated by calling function */
2897 short IPO_GetChannels (Ipo *ipo, IPO_Channel *channels)
2898 {
2899         IpoCurve *icu;
2900         int total = 0;
2901         
2902         /* don't do anything with no IPO-block */
2903         if (ipo == NULL) 
2904                 return 0;
2905         
2906         /* store the IPO-curve's adrcode in the relevant channel slot */
2907         for (icu=ipo->curve.first; (icu) && (total < 31); icu=icu->next, total++)
2908                 channels[total]= icu->adrcode;
2909         
2910         /* return the number of channels stored */
2911         return total;
2912 }
2913
2914 /* Get the float value for channel 'channel' at time 'ctime' */
2915 float IPO_GetFloatValue (Ipo *ipo, IPO_Channel channel, float ctime)