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