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